Skip to content

Commit b8c54d9

Browse files
committed
[analyzer] Splitting TaintPropagation checker into reporting and modeling checkers
Taint propagation is a a generic modeling feature of the Clang Static Analyzer which many other checkers depend on. Therefore GenericTaintChecker is split into a TaintPropagation modeling checker and a GenericTaint reporting checker. Other checkers, which report taint related warnings, should set the TaintPropagation checker as their dependency.
1 parent 221d5c5 commit b8c54d9

File tree

4 files changed

+42
-16
lines changed

4 files changed

+42
-16
lines changed

clang/docs/analyzer/checkers.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3011,10 +3011,10 @@ alpha.security.taint
30113011
Checkers implementing
30123012
`taint analysis <https://en.wikipedia.org/wiki/Taint_checking>`_.
30133013
3014-
.. _alpha-security-taint-TaintPropagation:
3014+
.. _alpha-security-taint-GenericTaint:
30153015
3016-
alpha.security.taint.TaintPropagation (C, C++)
3017-
""""""""""""""""""""""""""""""""""""""""""""""
3016+
alpha.security.taint.GenericTaint (C, C++)
3017+
""""""""""""""""""""""""""""""""""""""""""
30183018
30193019
Taint analysis identifies potential security vulnerabilities where the
30203020
attacker can inject malicious data to the program to execute an attack

clang/docs/analyzer/user-docs/TaintAnalysisConfiguration.rst

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@
22
Taint Analysis Configuration
33
============================
44

5-
The Clang Static Analyzer uses taint analysis to detect security-related issues in code.
6-
The backbone of taint analysis in the Clang SA is the `GenericTaintChecker`, which the user can access via the :ref:`alpha-security-taint-TaintPropagation` checker alias and this checker has a default taint-related configuration.
7-
The built-in default settings are defined in code, and they are always in effect once the checker is enabled, either directly or via the alias.
8-
The checker also provides a configuration interface for extending the default settings by providing a configuration file in `YAML <http://llvm.org/docs/YamlIO.html#introduction-to-yaml>`_ format.
5+
The Clang Static Analyzer uses taint analysis to detect injection vulnerability related issues in code.
6+
The backbone of taint analysis in the Clang SA is the `TaintPropagation` modeling checker.
7+
The reports are emitted via the :ref:`alpha-security-taint-GenericTaint` checker.
8+
The `TaintPropagation` checker has a default taint-related configuration.
9+
The built-in default settings are defined in code, and they are always in effect.
10+
The checker also provides a configuration interface for extending the default settings via the ``alpha.security.taint.TaintPropagation:Config`` checker config parameter
11+
by providing a configuration file to the in `YAML <http://llvm.org/docs/YamlIO.html#introduction-to-yaml>`_ format.
912
This documentation describes the syntax of the configuration file and gives the informal semantics of the configuration options.
1013

1114
.. contents::

clang/include/clang/StaticAnalyzer/Checkers/Checkers.td

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1071,7 +1071,7 @@ def ReturnPointerRangeChecker : Checker<"ReturnPtrRange">,
10711071

10721072
let ParentPackage = Taint in {
10731073

1074-
def GenericTaintChecker : Checker<"TaintPropagation">,
1074+
def TaintPropagationChecker : Checker<"TaintPropagation">, // Modelling checker
10751075
HelpText<"Generate taint information used by other checkers">,
10761076
CheckerOptions<[
10771077
CmdLineOption<String,
@@ -1080,6 +1080,12 @@ def GenericTaintChecker : Checker<"TaintPropagation">,
10801080
"",
10811081
InAlpha>,
10821082
]>,
1083+
Documentation<NotDocumented>,
1084+
Hidden;
1085+
1086+
def GenericTaintChecker : Checker<"GenericTaint">,
1087+
HelpText<"Reports potential injection vulnerabilities">,
1088+
Dependencies<[TaintPropagationChecker]>,
10831089
Documentation<HasDocumentation>;
10841090

10851091
} // end "alpha.security.taint"
@@ -1717,9 +1723,7 @@ let ParentPackage = TaintOptIn in {
17171723
def TaintedAllocChecker: Checker<"TaintedAlloc">,
17181724
HelpText<"Check for memory allocations, where the size parameter "
17191725
"might be a tainted (attacker controlled) value.">,
1720-
Dependencies<[DynamicMemoryModeling]>,
1721-
//FIXME: GenericTaintChecker should be a dependency, but only after it
1722-
//is transformed into a modeling checker
1726+
Dependencies<[DynamicMemoryModeling, TaintPropagationChecker]>,
17231727
Documentation<HasDocumentation>;
17241728

17251729
} // end "optin.taint"

clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
2828
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
2929
#include "llvm/ADT/StringExtras.h"
30+
#include "llvm/ADT/StringRef.h"
3031
#include "llvm/Support/YAMLTraits.h"
3132

3233
#include <limits>
@@ -391,8 +392,11 @@ class GenericTaintChecker : public Checker<check::PreCall, check::PostCall> {
391392
bool generateReportIfTainted(const Expr *E, StringRef Msg,
392393
CheckerContext &C) const;
393394

395+
bool isTaintReporterCheckerEnabled = false;
396+
CheckerNameRef reporterCheckerName;
397+
394398
private:
395-
const BugType BT{this, "Use of Untrusted Data", categories::TaintedData};
399+
mutable std::unique_ptr<BugType> BT;
396400

397401
bool checkUncontrolledFormatString(const CallEvent &Call,
398402
CheckerContext &C) const;
@@ -1033,20 +1037,25 @@ bool GenericTaintRule::UntrustedEnv(CheckerContext &C) {
10331037
bool GenericTaintChecker::generateReportIfTainted(const Expr *E, StringRef Msg,
10341038
CheckerContext &C) const {
10351039
assert(E);
1040+
if (!isTaintReporterCheckerEnabled)
1041+
return false;
10361042
std::optional<SVal> TaintedSVal =
10371043
getTaintedPointeeOrPointer(C.getState(), C.getSVal(E));
10381044

10391045
if (!TaintedSVal)
10401046
return false;
10411047

10421048
// Generate diagnostic.
1043-
if (ExplodedNode *N = C.generateNonFatalErrorNode()) {
1044-
auto report = std::make_unique<PathSensitiveBugReport>(BT, Msg, N);
1049+
if (!BT)
1050+
BT.reset(new BugType(reporterCheckerName, "Use of Untrusted Data",
1051+
categories::TaintedData));
1052+
static CheckerProgramPointTag Tag(reporterCheckerName, Msg);
1053+
if (ExplodedNode *N = C.generateNonFatalErrorNode(C.getState(), &Tag)) {
1054+
auto report = std::make_unique<PathSensitiveBugReport>(*BT, Msg, N);
10451055
report->addRange(E->getSourceRange());
10461056
for (auto TaintedSym : getTaintedSymbols(C.getState(), *TaintedSVal)) {
10471057
report->markInteresting(TaintedSym);
10481058
}
1049-
10501059
C.emitReport(std::move(report));
10511060
return true;
10521061
}
@@ -1122,10 +1131,20 @@ void GenericTaintChecker::taintUnsafeSocketProtocol(const CallEvent &Call,
11221131
}
11231132

11241133
/// Checker registration
1125-
void ento::registerGenericTaintChecker(CheckerManager &Mgr) {
1134+
void ento::registerTaintPropagationChecker(CheckerManager &Mgr) {
11261135
Mgr.registerChecker<GenericTaintChecker>();
11271136
}
11281137

1138+
bool ento::shouldRegisterTaintPropagationChecker(const CheckerManager &mgr) {
1139+
return true;
1140+
}
1141+
1142+
void ento::registerGenericTaintChecker(CheckerManager &Mgr) {
1143+
GenericTaintChecker *checker = Mgr.getChecker<GenericTaintChecker>();
1144+
checker->isTaintReporterCheckerEnabled = true;
1145+
checker->reporterCheckerName = Mgr.getCurrentCheckerName();
1146+
}
1147+
11291148
bool ento::shouldRegisterGenericTaintChecker(const CheckerManager &mgr) {
11301149
return true;
11311150
}

0 commit comments

Comments
 (0)