Skip to content

Commit e6daf3b

Browse files
committed
CPP: Support taint flow to qualifiers.
1 parent 974994e commit e6daf3b

File tree

4 files changed

+33
-4
lines changed

4 files changed

+33
-4
lines changed

cpp/ql/src/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,11 @@ predicate localAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeT
6868
)
6969
or
7070
// Taint can flow through modeled functions
71+
exprToExprStep(nodeFrom.asExpr(), nodeTo.asExpr())
72+
or
7173
exprToDefinitionByReferenceStep(nodeFrom.asExpr(), nodeTo.asDefiningArgument())
7274
or
73-
exprToExprStep(nodeFrom.asExpr(), nodeTo.asExpr())
75+
exprToPartialDefinitionStep(nodeFrom.asExpr(), nodeTo.asPartialDefinition())
7476
}
7577

7678
/**
@@ -187,3 +189,24 @@ private predicate exprToDefinitionByReferenceStep(Expr exprIn, Expr argOut) {
187189
)
188190
)
189191
}
192+
193+
private predicate exprToPartialDefinitionStep(Expr exprIn, Expr exprOut) {
194+
exists(TaintFunction f, Call call, FunctionInput inModel, FunctionOutput outModel |
195+
call.getTarget() = f and
196+
(
197+
exprOut = call.getQualifier() and
198+
outModel.isQualifierObject()
199+
) and
200+
f.hasTaintFlow(inModel, outModel) and
201+
exists(int argInIndex |
202+
inModel.isParameterDeref(argInIndex) and
203+
exprIn = call.getArgument(argInIndex)
204+
or
205+
inModel.isParameterDeref(argInIndex) and
206+
call.passesByReference(argInIndex, exprIn)
207+
or
208+
inModel.isParameter(argInIndex) and
209+
exprIn = call.getArgument(argInIndex)
210+
)
211+
)
212+
}

cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,7 @@ void test_qualifiers()
420420
sink(a);
421421
sink(a.getMember());
422422
a.setMember(source());
423-
sink(a); // tainted [NOT DETECTED]
423+
sink(a); // tainted
424424
sink(a.getMember()); // tainted [NOT DETECTED]
425425

426426
sink(b);
@@ -435,14 +435,14 @@ void test_qualifiers()
435435
sink(c);
436436
sink(c->getMember());
437437
c->setMember(source());
438-
sink(c); // tainted (deref) [NOT DETECTED]
438+
sink(c); // tainted (deref)
439439
sink(c->getMember()); // tainted [NOT DETECTED]
440440

441441
delete c;
442442

443443
sink(d);
444444
sink(d.getString());
445445
d.setString(strings::source());
446-
sink(d); // tainted [NOT DETECTED]
446+
sink(d); // tainted
447447
sink(d.getString()); // tainted [NOT DETECTED]
448448
}

cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,7 @@
3939
| taint.cpp:352:7:352:7 | b | taint.cpp:330:6:330:11 | call to source |
4040
| taint.cpp:372:7:372:7 | a | taint.cpp:365:24:365:29 | source |
4141
| taint.cpp:391:7:391:7 | a | taint.cpp:385:27:385:32 | source |
42+
| taint.cpp:423:7:423:7 | a | taint.cpp:422:14:422:19 | call to source |
4243
| taint.cpp:430:9:430:14 | member | taint.cpp:428:13:428:18 | call to source |
44+
| taint.cpp:438:7:438:7 | c | taint.cpp:437:15:437:20 | call to source |
45+
| taint.cpp:446:7:446:7 | d | taint.cpp:445:14:445:28 | call to source |

cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,8 @@
2626
| taint.cpp:352:7:352:7 | taint.cpp:330:6:330:11 | AST only |
2727
| taint.cpp:372:7:372:7 | taint.cpp:365:24:365:29 | AST only |
2828
| taint.cpp:391:7:391:7 | taint.cpp:385:27:385:32 | AST only |
29+
| taint.cpp:423:7:423:7 | taint.cpp:422:14:422:19 | AST only |
2930
| taint.cpp:429:7:429:7 | taint.cpp:428:13:428:18 | IR only |
3031
| taint.cpp:430:9:430:14 | taint.cpp:428:13:428:18 | AST only |
32+
| taint.cpp:438:7:438:7 | taint.cpp:437:15:437:20 | AST only |
33+
| taint.cpp:446:7:446:7 | taint.cpp:445:14:445:28 | AST only |

0 commit comments

Comments
 (0)