Skip to content

Commit 0d0ab91

Browse files
committed
C++: Address review comments
1 parent de4e2a2 commit 0d0ab91

File tree

1 file changed

+18
-12
lines changed

1 file changed

+18
-12
lines changed

cpp/ql/src/semmle/code/cpp/ir/dataflow/DefaultTaintTracking.qll

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -60,14 +60,13 @@ private predicate accessesVariable(CopyInstruction copy, Variable var) {
6060
/**
6161
* A variable that has any kind of upper-bound check anywhere in the program
6262
*/
63+
// TODO: This coarse overapproximation, ported from the old taint tracking
64+
// library, could be replaced with an actual semantic check that a particular
65+
// variable _access_ is guarded by an upper-bound check. We probably don't want
66+
// to do this right away since it could expose a lot of FPs that were
67+
// previously suppressed by this predicate by coincidence.
6368
private predicate hasUpperBoundsCheck(Variable var) {
64-
exists(BinaryOperation oper, VariableAccess access |
65-
(
66-
oper.getOperator() = "<" or
67-
oper.getOperator() = "<=" or
68-
oper.getOperator() = ">" or
69-
oper.getOperator() = ">="
70-
) and
69+
exists(RelationalOperation oper, VariableAccess access |
7170
oper.getLeftOperand() = access and
7271
access.getTarget() = var and
7372
// Comparing to 0 is not an upper bound check
@@ -101,19 +100,26 @@ private predicate instructionTaintStep(Instruction i1, Instruction i2) {
101100
// through `LoadInstruction`.
102101
//
103102
// TODO: Flow from argument to return of known functions: Port missing parts
104-
// of `returnArgument` to the `interfaces.Taint` library.
103+
// of `returnArgument` to the `interfaces.Taint` and `interfaces.DataFlow`
104+
// libraries.
105105
//
106106
// TODO: Flow from input argument to output argument of known functions: Port
107-
// missing parts of `copyValueBetweenArguments` to the `interfaces.Taint`
108-
// library and implement call side-effect nodes. This will help with the test
109-
// for `ExecTainted.ql`. The test for `TaintedPath.ql` is more tricky because
110-
// the output arg is a pointer addition expression.
107+
// missing parts of `copyValueBetweenArguments` to the `interfaces.Taint` and
108+
// `interfaces.DataFlow` libraries and implement call side-effect nodes. This
109+
// will help with the test for `ExecTainted.ql`. The test for
110+
// `TaintedPath.ql` is more tricky because the output arg is a pointer
111+
// addition expression.
111112
}
112113

113114
predicate tainted(Expr source, Element tainted) {
114115
exists(DefaultTaintTrackingCfg cfg, DataFlow::Node sink |
115116
cfg.hasFlow(DataFlow::exprNode(source), sink)
116117
|
118+
// TODO: is it more appropriate to use asConvertedExpr here and avoid
119+
// `getConversion*`? Or will that cause us to miss some cases where there's
120+
// flow to a conversion (like a `ReferenceDereferenceExpr`) and we want to
121+
// pretend there was flow to the converted `Expr` for the sake of
122+
// compatibility.
117123
sink.asExpr().getConversion*() = tainted
118124
or
119125
// For compatibility, send flow from arguments to parameters, even for

0 commit comments

Comments
 (0)