diff --git a/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp b/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp --- a/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp @@ -36,6 +36,7 @@ enum OOB_Kind { OOB_Precedes, OOB_Excedes, OOB_Tainted }; void reportOOB(CheckerContext &C, ProgramStateRef errorState, OOB_Kind kind, + SVal InterestingValue = UndefinedVal(), std::unique_ptr Visitor = nullptr) const; public: @@ -206,6 +207,7 @@ if (state_exceedsUpperBound && state_withinUpperBound) { if (isTainted(state, *upperboundToCheck)) { reportOOB(checkerContext, state_exceedsUpperBound, OOB_Tainted, + *upperboundToCheck, std::make_unique(*upperboundToCheck)); return; } @@ -227,7 +229,7 @@ void ArrayBoundCheckerV2::reportOOB( CheckerContext &checkerContext, ProgramStateRef errorState, OOB_Kind kind, - std::unique_ptr Visitor) const { + SVal InterestingValue, std::unique_ptr Visitor) const { ExplodedNode *errorNode = checkerContext.generateErrorNode(errorState); if (!errorNode) @@ -255,6 +257,7 @@ } auto BR = std::make_unique(*BT, os.str(), errorNode); + BR->markInteresting(InterestingValue); BR->addVisitor(std::move(Visitor)); checkerContext.emitReport(std::move(BR)); } diff --git a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp --- a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -60,6 +60,7 @@ #include "clang/Basic/TargetInfo.h" #include "clang/Lex/Lexer.h" #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" +#include "clang/StaticAnalyzer/Checkers/Taint.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h" #include "clang/StaticAnalyzer/Core/Checker.h" @@ -1763,6 +1764,15 @@ // Set the region's extent. State = setDynamicExtent(State, RetVal.getAsRegion(), Size.castAs(), svalBuilder); + if (taint::isTainted(State, Size)) { + const NoteTag *Note = + C.getNoteTag([Size](PathSensitiveBugReport &BR) -> std::string { + if (BR.isInteresting(Size)) + return "Allocating tainted amount of memory"; + return ""; + }); + Pred = C.addTransition(State, Pred, Note); + } return MallocUpdateRefState(C, CE, State, Pred, Family); } diff --git a/clang/test/Analysis/taint-diagnostic-visitor.c b/clang/test/Analysis/taint-diagnostic-visitor.c --- a/clang/test/Analysis/taint-diagnostic-visitor.c +++ b/clang/test/Analysis/taint-diagnostic-visitor.c @@ -46,6 +46,7 @@ int *p = (int *)malloc(x + conj); // Generic taint checker forbids tainted allocation. // expected-warning@-1 {{Untrusted data is used to specify the buffer size}} // expected-note@-2 {{Untrusted data is used to specify the buffer size}} + // expected-note@-3 {{Allocating tainted amount of memory}} p[1] = 1; // BoundsV2 checker can not prove that the access is safe. // expected-warning@-1 {{Out of bound memory access (index is tainted)}}