mirror of
https://github.com/github/codeql.git
synced 2026-05-01 03:35:13 +02:00
C++: noisy output iterators in AST taint tracking
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
|
||||
private import semmle.code.cpp.models.interfaces.DataFlow
|
||||
private import semmle.code.cpp.models.interfaces.Taint
|
||||
private import semmle.code.cpp.models.implementations.Iterator
|
||||
|
||||
private module DataFlow {
|
||||
import semmle.code.cpp.dataflow.internal.DataFlowUtil
|
||||
@@ -186,6 +187,12 @@ private predicate exprToExprStep(Expr exprIn, Expr exprOut) {
|
||||
exprIn = call.getQualifier()
|
||||
)
|
||||
)
|
||||
or
|
||||
exists(Variable iterator, Variable collection |
|
||||
assignmentViaIterator(iterator, exprIn) and
|
||||
isIteratorForCollection(iterator, collection) and
|
||||
collection.getAnAccess() = exprOut
|
||||
)
|
||||
}
|
||||
|
||||
private predicate exprToDefinitionByReferenceStep(Expr exprIn, Expr argOut) {
|
||||
@@ -249,3 +256,27 @@ private predicate exprToPartialDefinitionStep(Expr exprIn, Expr exprOut) {
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate isIteratorForCollection(Variable iterator, Variable collection) {
|
||||
exists(Call beginOrEnd |
|
||||
beginOrEnd.getTarget() instanceof BeginOrEndFunction and
|
||||
beginOrEnd.getQualifier() = collection.getAnAccess() and
|
||||
iterator.getAnAssignedValue() = beginOrEnd
|
||||
)
|
||||
}
|
||||
|
||||
private predicate assignmentViaIterator(Variable iterator, Expr rvalue) {
|
||||
exists(Assignment a, Call c |
|
||||
c.getTarget() instanceof IteratorArrayMemberOperator and
|
||||
c.getQualifier() = iterator.getAnAccess()
|
||||
or
|
||||
c.getTarget() instanceof IteratorPointerDereferenceMemberOperator and
|
||||
c.getQualifier() = iterator.getAnAccess()
|
||||
or
|
||||
c.getTarget() instanceof IteratorPointerDereferenceOperator and
|
||||
c.getArgument(0) = iterator.getAnAccess()
|
||||
|
|
||||
c = a.getLValue() and
|
||||
rvalue = a.getRValue()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -271,3 +271,15 @@ class IteratorArrayMemberOperator extends MemberFunction, TaintFunction {
|
||||
output.isReturnValue()
|
||||
}
|
||||
}
|
||||
|
||||
class BeginOrEndFunction extends MemberFunction, TaintFunction {
|
||||
BeginOrEndFunction() {
|
||||
this.hasName(["begin", "cbegin", "rbegin", "crbegin", "end", "cend", "rend", "crend"]) and
|
||||
this.getType().getUnspecifiedType() instanceof Iterator
|
||||
}
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
input.isQualifierObject() and
|
||||
output.isReturnValue()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3197,7 +3197,10 @@
|
||||
| vector.cpp:336:37:336:41 | call to begin | vector.cpp:337:3:337:4 | i1 | |
|
||||
| vector.cpp:337:2:337:15 | ... = ... | vector.cpp:337:2:337:2 | call to operator* [post update] | |
|
||||
| vector.cpp:337:3:337:4 | i1 | vector.cpp:337:2:337:2 | call to operator* | TAINT |
|
||||
| vector.cpp:337:8:337:13 | call to source | vector.cpp:336:34:336:35 | v1 | TAINT |
|
||||
| vector.cpp:337:8:337:13 | call to source | vector.cpp:337:2:337:15 | ... = ... | |
|
||||
| vector.cpp:337:8:337:13 | call to source | vector.cpp:338:7:338:8 | v1 | TAINT |
|
||||
| vector.cpp:337:8:337:13 | call to source | vector.cpp:354:1:354:1 | v1 | TAINT |
|
||||
| vector.cpp:338:7:338:8 | ref arg v1 | vector.cpp:354:1:354:1 | v1 | |
|
||||
| vector.cpp:340:38:340:39 | ref arg v2 | vector.cpp:340:56:340:57 | v2 | |
|
||||
| vector.cpp:340:38:340:39 | ref arg v2 | vector.cpp:343:7:343:8 | v2 | |
|
||||
@@ -3216,7 +3219,11 @@
|
||||
| vector.cpp:340:68:340:69 | ref arg it | vector.cpp:341:4:341:5 | it | |
|
||||
| vector.cpp:341:3:341:16 | ... = ... | vector.cpp:341:3:341:3 | call to operator* [post update] | |
|
||||
| vector.cpp:341:4:341:5 | it | vector.cpp:341:3:341:3 | call to operator* | TAINT |
|
||||
| vector.cpp:341:9:341:14 | call to source | vector.cpp:340:38:340:39 | v2 | TAINT |
|
||||
| vector.cpp:341:9:341:14 | call to source | vector.cpp:340:56:340:57 | v2 | TAINT |
|
||||
| vector.cpp:341:9:341:14 | call to source | vector.cpp:341:3:341:16 | ... = ... | |
|
||||
| vector.cpp:341:9:341:14 | call to source | vector.cpp:343:7:343:8 | v2 | TAINT |
|
||||
| vector.cpp:341:9:341:14 | call to source | vector.cpp:354:1:354:1 | v2 | TAINT |
|
||||
| vector.cpp:343:7:343:8 | ref arg v2 | vector.cpp:354:1:354:1 | v2 | |
|
||||
| vector.cpp:345:15:345:15 | (__begin) | vector.cpp:345:15:345:15 | call to operator* | TAINT |
|
||||
| vector.cpp:345:15:345:15 | (__begin) | vector.cpp:345:15:345:15 | call to operator++ | TAINT |
|
||||
@@ -3253,5 +3260,9 @@
|
||||
| vector.cpp:350:68:350:69 | ref arg it | vector.cpp:351:4:351:5 | it | |
|
||||
| vector.cpp:351:3:351:16 | ... = ... | vector.cpp:351:3:351:3 | call to operator* [post update] | |
|
||||
| vector.cpp:351:4:351:5 | it | vector.cpp:351:3:351:3 | call to operator* | TAINT |
|
||||
| vector.cpp:351:9:351:14 | call to source | vector.cpp:350:38:350:39 | v4 | TAINT |
|
||||
| vector.cpp:351:9:351:14 | call to source | vector.cpp:350:56:350:57 | v4 | TAINT |
|
||||
| vector.cpp:351:9:351:14 | call to source | vector.cpp:351:3:351:16 | ... = ... | |
|
||||
| vector.cpp:351:9:351:14 | call to source | vector.cpp:353:7:353:8 | v4 | TAINT |
|
||||
| vector.cpp:351:9:351:14 | call to source | vector.cpp:354:1:354:1 | v4 | TAINT |
|
||||
| vector.cpp:353:7:353:8 | ref arg v4 | vector.cpp:354:1:354:1 | v4 | |
|
||||
|
||||
@@ -326,3 +326,6 @@
|
||||
| vector.cpp:312:7:312:7 | d | vector.cpp:303:14:303:19 | call to source |
|
||||
| vector.cpp:324:7:324:8 | v2 | vector.cpp:318:15:318:20 | call to source |
|
||||
| vector.cpp:326:7:326:8 | v4 | vector.cpp:318:15:318:20 | call to source |
|
||||
| vector.cpp:338:7:338:8 | v1 | vector.cpp:337:8:337:13 | call to source |
|
||||
| vector.cpp:343:7:343:8 | v2 | vector.cpp:341:9:341:14 | call to source |
|
||||
| vector.cpp:353:7:353:8 | v4 | vector.cpp:351:9:351:14 | call to source |
|
||||
|
||||
@@ -275,3 +275,6 @@
|
||||
| vector.cpp:312:7:312:7 | vector.cpp:303:14:303:19 | AST only |
|
||||
| vector.cpp:324:7:324:8 | vector.cpp:318:15:318:20 | AST only |
|
||||
| vector.cpp:326:7:326:8 | vector.cpp:318:15:318:20 | AST only |
|
||||
| vector.cpp:338:7:338:8 | vector.cpp:337:8:337:13 | AST only |
|
||||
| vector.cpp:343:7:343:8 | vector.cpp:341:9:341:14 | AST only |
|
||||
| vector.cpp:353:7:353:8 | vector.cpp:351:9:351:14 | AST only |
|
||||
|
||||
@@ -21,7 +21,7 @@ void test_range_based_for_loop_vector(int source1) {
|
||||
}
|
||||
|
||||
for(std::vector<int>::iterator it = v.begin(); it != v.end(); ++it) {
|
||||
sink(*it); // tainted
|
||||
sink(*it); // tainted [NOT DETECTED by IR]
|
||||
}
|
||||
|
||||
for(int& x : v) {
|
||||
@@ -335,12 +335,12 @@ void test_vector_output_iterator() {
|
||||
|
||||
std::vector<int>::iterator i1 = v1.begin();
|
||||
*i1 = source();
|
||||
sink(v1); // tainted [NOT DETECTED]
|
||||
sink(v1); // tainted [NOT DETECTED by IR]
|
||||
|
||||
for(std::vector<int>::iterator it = v2.begin(); it != v2.end(); ++it) {
|
||||
*it = source(); // tainted [NOT DETECTED]
|
||||
*it = source();
|
||||
}
|
||||
sink(v2);
|
||||
sink(v2); // tainted [NOT DETECTED by IR]
|
||||
|
||||
for(int& x : v3) {
|
||||
x = source();
|
||||
@@ -350,5 +350,5 @@ void test_vector_output_iterator() {
|
||||
for(std::vector<int>::iterator it = v4.begin(); it != v4.end(); ++it) {
|
||||
*it = source();
|
||||
}
|
||||
sink(v4); // tainted [NOT DETECTED]
|
||||
sink(v4); // tainted [NOT DETECTED by IR]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user