|
6 | 6 | //
|
7 | 7 | //===----------------------------------------------------------------------===//
|
8 | 8 |
|
| 9 | +#include "Taint.h" |
9 | 10 | #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
|
10 | 11 | #include "clang/StaticAnalyzer/Checkers/SValExplainer.h"
|
11 | 12 | #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
|
@@ -46,6 +47,7 @@ class ExprInspectionChecker : public Checker<eval::Call, check::DeadSymbols,
|
46 | 47 | void analyzerHashDump(const CallExpr *CE, CheckerContext &C) const;
|
47 | 48 | void analyzerDenote(const CallExpr *CE, CheckerContext &C) const;
|
48 | 49 | void analyzerExpress(const CallExpr *CE, CheckerContext &C) const;
|
| 50 | + void analyzerIsTainted(const CallExpr *CE, CheckerContext &C) const; |
49 | 51 |
|
50 | 52 | typedef void (ExprInspectionChecker::*FnCheck)(const CallExpr *,
|
51 | 53 | CheckerContext &C) const;
|
@@ -73,26 +75,34 @@ bool ExprInspectionChecker::evalCall(const CallEvent &Call,
|
73 | 75 |
|
74 | 76 | // These checks should have no effect on the surrounding environment
|
75 | 77 | // (globals should not be invalidated, etc), hence the use of evalCall.
|
76 |
| - FnCheck Handler = llvm::StringSwitch<FnCheck>(C.getCalleeName(CE)) |
77 |
| - .Case("clang_analyzer_eval", &ExprInspectionChecker::analyzerEval) |
78 |
| - .Case("clang_analyzer_checkInlined", |
79 |
| - &ExprInspectionChecker::analyzerCheckInlined) |
80 |
| - .Case("clang_analyzer_crash", &ExprInspectionChecker::analyzerCrash) |
81 |
| - .Case("clang_analyzer_warnIfReached", |
82 |
| - &ExprInspectionChecker::analyzerWarnIfReached) |
83 |
| - .Case("clang_analyzer_warnOnDeadSymbol", |
84 |
| - &ExprInspectionChecker::analyzerWarnOnDeadSymbol) |
85 |
| - .StartsWith("clang_analyzer_explain", &ExprInspectionChecker::analyzerExplain) |
86 |
| - .StartsWith("clang_analyzer_dump", &ExprInspectionChecker::analyzerDump) |
87 |
| - .Case("clang_analyzer_getExtent", &ExprInspectionChecker::analyzerGetExtent) |
88 |
| - .Case("clang_analyzer_printState", |
89 |
| - &ExprInspectionChecker::analyzerPrintState) |
90 |
| - .Case("clang_analyzer_numTimesReached", |
91 |
| - &ExprInspectionChecker::analyzerNumTimesReached) |
92 |
| - .Case("clang_analyzer_hashDump", &ExprInspectionChecker::analyzerHashDump) |
93 |
| - .Case("clang_analyzer_denote", &ExprInspectionChecker::analyzerDenote) |
94 |
| - .Case("clang_analyzer_express", &ExprInspectionChecker::analyzerExpress) |
95 |
| - .Default(nullptr); |
| 78 | + FnCheck Handler = |
| 79 | + llvm::StringSwitch<FnCheck>(C.getCalleeName(CE)) |
| 80 | + .Case("clang_analyzer_eval", &ExprInspectionChecker::analyzerEval) |
| 81 | + .Case("clang_analyzer_checkInlined", |
| 82 | + &ExprInspectionChecker::analyzerCheckInlined) |
| 83 | + .Case("clang_analyzer_crash", &ExprInspectionChecker::analyzerCrash) |
| 84 | + .Case("clang_analyzer_warnIfReached", |
| 85 | + &ExprInspectionChecker::analyzerWarnIfReached) |
| 86 | + .Case("clang_analyzer_warnOnDeadSymbol", |
| 87 | + &ExprInspectionChecker::analyzerWarnOnDeadSymbol) |
| 88 | + .StartsWith("clang_analyzer_explain", |
| 89 | + &ExprInspectionChecker::analyzerExplain) |
| 90 | + .StartsWith("clang_analyzer_dump", |
| 91 | + &ExprInspectionChecker::analyzerDump) |
| 92 | + .Case("clang_analyzer_getExtent", |
| 93 | + &ExprInspectionChecker::analyzerGetExtent) |
| 94 | + .Case("clang_analyzer_printState", |
| 95 | + &ExprInspectionChecker::analyzerPrintState) |
| 96 | + .Case("clang_analyzer_numTimesReached", |
| 97 | + &ExprInspectionChecker::analyzerNumTimesReached) |
| 98 | + .Case("clang_analyzer_hashDump", |
| 99 | + &ExprInspectionChecker::analyzerHashDump) |
| 100 | + .Case("clang_analyzer_denote", &ExprInspectionChecker::analyzerDenote) |
| 101 | + .Case("clang_analyzer_express", |
| 102 | + &ExprInspectionChecker::analyzerExpress) |
| 103 | + .StartsWith("clang_analyzer_isTainted", |
| 104 | + &ExprInspectionChecker::analyzerIsTainted) |
| 105 | + .Default(nullptr); |
96 | 106 |
|
97 | 107 | if (!Handler)
|
98 | 108 | return false;
|
@@ -412,6 +422,17 @@ void ExprInspectionChecker::analyzerExpress(const CallExpr *CE,
|
412 | 422 | reportBug(*Str, C);
|
413 | 423 | }
|
414 | 424 |
|
| 425 | +void ExprInspectionChecker::analyzerIsTainted(const CallExpr *CE, |
| 426 | + CheckerContext &C) const { |
| 427 | + if (CE->getNumArgs() != 1) { |
| 428 | + reportBug("clang_analyzer_isTainted() requires exactly one argument", C); |
| 429 | + return; |
| 430 | + } |
| 431 | + const bool IsTainted = |
| 432 | + taint::isTainted(C.getState(), CE->getArg(0), C.getLocationContext()); |
| 433 | + reportBug(IsTainted ? "YES" : "NO", C); |
| 434 | +} |
| 435 | + |
415 | 436 | void ento::registerExprInspectionChecker(CheckerManager &Mgr) {
|
416 | 437 | Mgr.registerChecker<ExprInspectionChecker>();
|
417 | 438 | }
|
|
0 commit comments