From 983f54f11a74736eed61075c24229032131d09a2 Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Tue, 25 Aug 2020 15:21:16 -0700 Subject: [PATCH 01/25] C++: simple tests for vector output iterators --- .../dataflow/taint-tests/localTaint.expected | 82 +++++++++++++++++++ .../dataflow/taint-tests/vector.cpp | 27 ++++++ 2 files changed, 109 insertions(+) diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected index 9a9fca0cd59e..bca6b6299adc 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected @@ -3173,3 +3173,85 @@ | vector.cpp:324:7:324:8 | ref arg v2 | vector.cpp:327:1:327:1 | v2 | | | vector.cpp:325:7:325:8 | ref arg v3 | vector.cpp:327:1:327:1 | v3 | | | vector.cpp:326:7:326:8 | ref arg v4 | vector.cpp:327:1:327:1 | v4 | | +| vector.cpp:329:62:329:65 | iter | vector.cpp:330:3:330:6 | iter | | +| vector.cpp:330:2:330:17 | ... = ... | vector.cpp:330:2:330:2 | call to operator* [post update] | | +| vector.cpp:330:3:330:6 | iter | vector.cpp:330:2:330:2 | call to operator* | TAINT | +| vector.cpp:330:10:330:15 | call to source | vector.cpp:330:2:330:17 | ... = ... | | +| vector.cpp:334:22:334:24 | call to vector | vector.cpp:336:34:336:35 | v1 | | +| vector.cpp:334:22:334:24 | call to vector | vector.cpp:338:7:338:8 | v1 | | +| vector.cpp:334:22:334:24 | call to vector | vector.cpp:354:1:354:1 | v1 | | +| vector.cpp:334:30:334:32 | call to vector | vector.cpp:340:38:340:39 | v2 | | +| vector.cpp:334:30:334:32 | call to vector | vector.cpp:340:56:340:57 | v2 | | +| vector.cpp:334:30:334:32 | call to vector | vector.cpp:343:7:343:8 | v2 | | +| vector.cpp:334:30:334:32 | call to vector | vector.cpp:354:1:354:1 | v2 | | +| vector.cpp:334:38:334:40 | call to vector | vector.cpp:345:15:345:16 | v3 | | +| vector.cpp:334:38:334:40 | call to vector | vector.cpp:348:7:348:8 | v3 | | +| vector.cpp:334:38:334:40 | call to vector | vector.cpp:354:1:354:1 | v3 | | +| vector.cpp:334:46:334:48 | call to vector | vector.cpp:350:38:350:39 | v4 | | +| vector.cpp:334:46:334:48 | call to vector | vector.cpp:350:56:350:57 | v4 | | +| vector.cpp:334:46:334:48 | call to vector | vector.cpp:353:7:353:8 | v4 | | +| vector.cpp:334:46:334:48 | call to vector | vector.cpp:354:1:354:1 | v4 | | +| vector.cpp:336:34:336:35 | ref arg v1 | vector.cpp:338:7:338:8 | v1 | | +| vector.cpp:336:34:336:35 | ref arg v1 | vector.cpp:354:1:354:1 | v1 | | +| vector.cpp:336:34:336:35 | v1 | vector.cpp:336:37:336:41 | call to begin | TAINT | +| 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:337:2:337:15 | ... = ... | | +| 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 | | +| vector.cpp:340:38:340:39 | ref arg v2 | vector.cpp:354:1:354:1 | v2 | | +| vector.cpp:340:38:340:39 | v2 | vector.cpp:340:41:340:45 | call to begin | TAINT | +| vector.cpp:340:41:340:45 | call to begin | vector.cpp:340:50:340:51 | it | | +| vector.cpp:340:41:340:45 | call to begin | vector.cpp:340:68:340:69 | it | | +| vector.cpp:340:41:340:45 | call to begin | vector.cpp:341:4:341:5 | it | | +| vector.cpp:340:56:340:57 | ref arg v2 | vector.cpp:340:56:340:57 | v2 | | +| vector.cpp:340:56:340:57 | ref arg v2 | vector.cpp:343:7:343:8 | v2 | | +| vector.cpp:340:56:340:57 | ref arg v2 | vector.cpp:354:1:354:1 | v2 | | +| vector.cpp:340:56:340:57 | v2 | vector.cpp:340:59:340:61 | call to end | TAINT | +| vector.cpp:340:68:340:69 | it | vector.cpp:340:66:340:66 | call to operator++ | TAINT | +| vector.cpp:340:68:340:69 | ref arg it | vector.cpp:340:50:340:51 | it | | +| vector.cpp:340:68:340:69 | ref arg it | vector.cpp:340:68:340:69 | it | | +| 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:341:3:341:16 | ... = ... | | +| 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 | +| vector.cpp:345:15:345:15 | (__end) | vector.cpp:345:15:345:15 | call to iterator | | +| vector.cpp:345:15:345:15 | (__range) | vector.cpp:345:15:345:15 | call to begin | TAINT | +| vector.cpp:345:15:345:15 | (__range) | vector.cpp:345:15:345:15 | call to end | TAINT | +| vector.cpp:345:15:345:15 | call to begin | vector.cpp:345:15:345:15 | (__begin) | | +| vector.cpp:345:15:345:15 | call to begin | vector.cpp:345:15:345:15 | (__begin) | | +| vector.cpp:345:15:345:15 | call to begin | vector.cpp:345:15:345:15 | (__begin) | | +| vector.cpp:345:15:345:15 | call to end | vector.cpp:345:15:345:15 | (__end) | | +| vector.cpp:345:15:345:15 | ref arg (__begin) | vector.cpp:345:15:345:15 | (__begin) | | +| vector.cpp:345:15:345:15 | ref arg (__begin) | vector.cpp:345:15:345:15 | (__begin) | | +| vector.cpp:345:15:345:15 | ref arg (__begin) | vector.cpp:345:15:345:15 | (__begin) | | +| vector.cpp:345:15:345:15 | ref arg (__range) | vector.cpp:345:15:345:15 | (__range) | | +| vector.cpp:345:15:345:16 | v3 | vector.cpp:345:15:345:15 | (__range) | | +| vector.cpp:345:15:345:16 | v3 | vector.cpp:345:15:345:15 | (__range) | | +| vector.cpp:345:15:345:16 | v3 | vector.cpp:345:15:345:15 | call to operator* | TAINT | +| vector.cpp:346:7:346:12 | call to source | vector.cpp:346:3:346:14 | ... = ... | | +| vector.cpp:348:7:348:8 | ref arg v3 | vector.cpp:354:1:354:1 | v3 | | +| vector.cpp:350:38:350:39 | ref arg v4 | vector.cpp:350:56:350:57 | v4 | | +| vector.cpp:350:38:350:39 | ref arg v4 | vector.cpp:353:7:353:8 | v4 | | +| vector.cpp:350:38:350:39 | ref arg v4 | vector.cpp:354:1:354:1 | v4 | | +| vector.cpp:350:38:350:39 | v4 | vector.cpp:350:41:350:45 | call to begin | TAINT | +| vector.cpp:350:41:350:45 | call to begin | vector.cpp:350:50:350:51 | it | | +| vector.cpp:350:41:350:45 | call to begin | vector.cpp:350:68:350:69 | it | | +| vector.cpp:350:41:350:45 | call to begin | vector.cpp:351:4:351:5 | it | | +| vector.cpp:350:56:350:57 | ref arg v4 | vector.cpp:350:56:350:57 | v4 | | +| vector.cpp:350:56:350:57 | ref arg v4 | vector.cpp:353:7:353:8 | v4 | | +| vector.cpp:350:56:350:57 | ref arg v4 | vector.cpp:354:1:354:1 | v4 | | +| vector.cpp:350:56:350:57 | v4 | vector.cpp:350:59:350:61 | call to end | TAINT | +| vector.cpp:350:68:350:69 | it | vector.cpp:350:66:350:66 | call to operator++ | TAINT | +| vector.cpp:350:68:350:69 | ref arg it | vector.cpp:350:50:350:51 | it | | +| vector.cpp:350:68:350:69 | ref arg it | vector.cpp:350:68:350:69 | it | | +| 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:351:3:351:16 | ... = ... | | +| vector.cpp:353:7:353:8 | ref arg v4 | vector.cpp:354:1:354:1 | v4 | | diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp index e2d12bed6c1d..6360438663ad 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp @@ -325,3 +325,30 @@ void test_constructors_more() { sink(v3); sink(v4); // tainted } + +void taint_vector_output_iterator(std::vector::iterator iter) { + *iter = source(); +} + +void test_vector_output_iterator() { + std::vector v1(10), v2(10), v3(10), v4(10); + + std::vector::iterator i1 = v1.begin(); + *i1 = source(); + sink(v1); // tainted [NOT DETECTED] + + for(std::vector::iterator it = v2.begin(); it != v2.end(); ++it) { + *it = source(); // tainted [NOT DETECTED] + } + sink(v2); + + for(int& x : v3) { + x = source(); + } + sink(v3); // tainted [NOT DETECTED] + + for(std::vector::iterator it = v4.begin(); it != v4.end(); ++it) { + *it = source(); + } + sink(v4); // tainted [NOT DETECTED] +} From 703db0b9a6ffdb53af4cef150cf1ae6f10ca4517 Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Tue, 25 Aug 2020 15:26:18 -0700 Subject: [PATCH 02/25] C++: noisy output iterators in AST taint tracking --- .../dataflow/internal/TaintTrackingUtil.qll | 31 +++++++++++++++++++ .../cpp/models/implementations/Iterator.qll | 12 +++++++ .../dataflow/taint-tests/localTaint.expected | 11 +++++++ .../dataflow/taint-tests/taint.expected | 3 ++ .../dataflow/taint-tests/test_diff.expected | 3 ++ .../dataflow/taint-tests/vector.cpp | 10 +++--- 6 files changed, 65 insertions(+), 5 deletions(-) diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll index a3f0c435e16e..c15f39c0c155 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll @@ -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() + ) +} diff --git a/cpp/ql/src/semmle/code/cpp/models/implementations/Iterator.qll b/cpp/ql/src/semmle/code/cpp/models/implementations/Iterator.qll index 2ad464d1634e..758d093bedc3 100644 --- a/cpp/ql/src/semmle/code/cpp/models/implementations/Iterator.qll +++ b/cpp/ql/src/semmle/code/cpp/models/implementations/Iterator.qll @@ -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() + } +} diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected index bca6b6299adc..0c0362206e1a 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected @@ -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 | | diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected index 15744c35716a..6697e57e4a34 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected @@ -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 | diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected index d4383d4e900f..7533d079093c 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected @@ -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 | diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp index 6360438663ad..f1cf4e914577 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp @@ -21,7 +21,7 @@ void test_range_based_for_loop_vector(int source1) { } for(std::vector::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::iterator i1 = v1.begin(); *i1 = source(); - sink(v1); // tainted [NOT DETECTED] + sink(v1); // tainted [NOT DETECTED by IR] for(std::vector::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::iterator it = v4.begin(); it != v4.end(); ++it) { *it = source(); } - sink(v4); // tainted [NOT DETECTED] + sink(v4); // tainted [NOT DETECTED by IR] } From c8cdf68bf9b8881faae02f89ca3cb5091ec1c926 Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Tue, 25 Aug 2020 16:34:36 -0700 Subject: [PATCH 03/25] C++: Remove StdStringBeginEnd --- .../cpp/models/implementations/Iterator.qll | 4 ++++ .../cpp/models/implementations/StdString.qll | 17 ----------------- 2 files changed, 4 insertions(+), 17 deletions(-) diff --git a/cpp/ql/src/semmle/code/cpp/models/implementations/Iterator.qll b/cpp/ql/src/semmle/code/cpp/models/implementations/Iterator.qll index 758d093bedc3..93a04d5ef900 100644 --- a/cpp/ql/src/semmle/code/cpp/models/implementations/Iterator.qll +++ b/cpp/ql/src/semmle/code/cpp/models/implementations/Iterator.qll @@ -272,6 +272,10 @@ class IteratorArrayMemberOperator extends MemberFunction, TaintFunction { } } +/** + * A `begin` or `end` member function, or a related member function, that + * returns an iterator. + */ class BeginOrEndFunction extends MemberFunction, TaintFunction { BeginOrEndFunction() { this.hasName(["begin", "cbegin", "rbegin", "crbegin", "end", "cend", "rend", "crend"]) and diff --git a/cpp/ql/src/semmle/code/cpp/models/implementations/StdString.qll b/cpp/ql/src/semmle/code/cpp/models/implementations/StdString.qll index 8e7cb24be73b..3a2c914eb4ce 100644 --- a/cpp/ql/src/semmle/code/cpp/models/implementations/StdString.qll +++ b/cpp/ql/src/semmle/code/cpp/models/implementations/StdString.qll @@ -212,23 +212,6 @@ class StdStringAssign extends TaintFunction { } } -/** - * The standard functions `std::string.begin` and `std::string.end` and their - * variants. - */ -class StdStringBeginEnd extends TaintFunction { - StdStringBeginEnd() { - this - .hasQualifiedName("std", "basic_string", - ["begin", "cbegin", "rbegin", "crbegin", "end", "cend", "rend", "crend"]) - } - - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input.isQualifierObject() and - output.isReturnValue() - } -} - /** * The standard function `std::string.copy`. */ From 13c45b6664a6b4fcad59a60a096236cb702d21b0 Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Thu, 27 Aug 2020 15:09:01 -0700 Subject: [PATCH 04/25] C++: remove unnecessary parameter in FlowVar.qll --- .../code/cpp/dataflow/internal/FlowVar.qll | 25 ++++++++----------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll index 6dc5da2f20bd..83941140fa62 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll @@ -240,7 +240,7 @@ module FlowVar_internal { ( initializer(v, sbb.getANode()) or - assignmentLikeOperation(sbb, v, _, _) + assignmentLikeOperation(sbb, v, _) or exists(PartialDefinition p | p.partiallyDefinesVariableAt(v, sbb)) or @@ -359,7 +359,7 @@ module FlowVar_internal { } override predicate definedByExpr(Expr e, ControlFlowNode node) { - assignmentLikeOperation(node, v, _, e) and + assignmentLikeOperation(node, v, e) and node = sbb or // We pick the defining `ControlFlowNode` of an `Initializer` to be its @@ -449,7 +449,7 @@ module FlowVar_internal { pragma[noinline] private Variable getAVariableAssignedInLoop() { exists(BasicBlock bbAssign | - assignmentLikeOperation(bbAssign.getANode(), result, _, _) and + assignmentLikeOperation(bbAssign.getANode(), result, _) and this.bbInLoop(bbAssign) ) } @@ -487,7 +487,7 @@ module FlowVar_internal { pragma[noinline] private predicate assignsToVar(BasicBlock bb, Variable v) { - assignmentLikeOperation(bb.getANode(), v, _, _) and + assignmentLikeOperation(bb.getANode(), v, _) and exists(AlwaysTrueUponEntryLoop loop | v = loop.getARelevantVariable()) } @@ -524,7 +524,7 @@ module FlowVar_internal { result = mid.getASuccessor() and variableLiveInSBB(result, v) and forall(AlwaysTrueUponEntryLoop loop | skipLoop(mid, result, v, loop) | loop.sbbInLoop(sbbDef)) and - not assignmentLikeOperation(result, v, _, _) + not assignmentLikeOperation(result, v, _) ) } @@ -566,7 +566,7 @@ module FlowVar_internal { * Holds if liveness of `v` should stop propagating backwards from `sbb`. */ private predicate variableNotLiveBefore(SubBasicBlock sbb, Variable v) { - assignmentLikeOperation(sbb, v, _, _) + assignmentLikeOperation(sbb, v, _) or // Liveness of `v` is killed when going backwards from a block that declares it exists(DeclStmt ds | ds.getADeclaration().(LocalVariable) = v and sbb.contains(ds)) @@ -687,20 +687,18 @@ module FlowVar_internal { * predicate. */ predicate assignmentLikeOperation( - ControlFlowNode node, Variable v, VariableAccess va, Expr assignedExpr + ControlFlowNode node, Variable v, Expr assignedExpr ) { // Together, the two following cases cover `Assignment` node = any(AssignExpr ae | - va = ae.getLValue() and - v = va.getTarget() and + v.getAnAccess() = ae.getLValue() and assignedExpr = ae.getRValue() ) or node = any(AssignOperation ao | - va = ao.getLValue() and - v = va.getTarget() and + v.getAnAccess() = ao.getLValue() and // Here and in the `PrefixCrementOperation` case, we say that the assigned // expression is the operation itself. For example, we say that `x += 1` // assigns `x += 1` to `x`. The justification is that after this operation, @@ -712,8 +710,7 @@ module FlowVar_internal { // `PrefixCrementOperation` is itself a source node = any(CrementOperation op | - va = op.getOperand() and - v = va.getTarget() and + v.getAnAccess() = op.getOperand() and assignedExpr = op ) } @@ -749,7 +746,7 @@ module FlowVar_internal { class DataFlowSubBasicBlockCutNode extends SubBasicBlockCutNode { DataFlowSubBasicBlockCutNode() { exists(Variable v | not fullySupportedSsaVariable(v) | - assignmentLikeOperation(this, v, _, _) + assignmentLikeOperation(this, v, _) or exists(PartialDefinition p | p.partiallyDefinesVariableAt(v, this)) // It is not necessary to cut the basic blocks at `Initializer` nodes From eab1557e27cfefef7b826960e3840e5ba79279e1 Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Tue, 8 Sep 2020 14:09:57 -0700 Subject: [PATCH 05/25] C++: output iterator flow via FlowVar --- .../cpp/dataflow/internal/DataFlowUtil.qll | 20 ++- .../code/cpp/dataflow/internal/FlowVar.qll | 98 +++++++++-- .../dataflow/internal/TaintTrackingUtil.qll | 34 +--- .../dataflow/taint-tests/localTaint.expected | 160 +++++++++++++++--- .../dataflow/taint-tests/taint.expected | 8 + .../dataflow/taint-tests/test_diff.expected | 8 + .../dataflow/taint-tests/vector.cpp | 32 +++- 7 files changed, 287 insertions(+), 73 deletions(-) diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll index 6647dda4072a..9705ca492ce9 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll @@ -283,12 +283,12 @@ abstract class PostUpdateNode extends Node { override Location getLocation() { result = getPreUpdateNode().getLocation() } } -private class PartialDefinitionNode extends PostUpdateNode, TPartialDefinitionNode { +private abstract class PartialDefinitionNode extends PostUpdateNode, TPartialDefinitionNode { PartialDefinition pd; - PartialDefinitionNode() { this = TPartialDefinitionNode(pd) } - - override Node getPreUpdateNode() { pd.definesExpressions(_, result.asExpr()) } + PartialDefinitionNode() { + this = TPartialDefinitionNode(pd) + } override Location getLocation() { result = pd.getActualLocation() } @@ -297,6 +297,18 @@ private class PartialDefinitionNode extends PostUpdateNode, TPartialDefinitionNo override string toString() { result = getPreUpdateNode().toString() + " [post update]" } } +private class VariablePartialDefinitionNode extends PartialDefinitionNode { + override VariablePartialDefinition pd; + + override Node getPreUpdateNode() { pd.definesExpressions(_, result.asExpr()) } +} + +private class IteratorPartialDefinitionNode extends PartialDefinitionNode { + override IteratorPartialDefinition pd; + + override Node getPreUpdateNode() { pd.definesExpressions(_, result.asExpr()) } +} + /** * A post-update node on the `e->f` in `f(&e->f)` (and other forms). */ diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll index 83941140fa62..cb2cdd68f082 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll @@ -6,6 +6,7 @@ import cpp private import semmle.code.cpp.controlflow.SSA private import semmle.code.cpp.dataflow.internal.SubBasicBlocks private import semmle.code.cpp.dataflow.internal.AddressFlow +private import semmle.code.cpp.models.implementations.Iterator /** * A conceptual variable that is assigned only once, like an SSA variable. This @@ -109,20 +110,16 @@ class FlowVar extends TFlowVar { */ private module PartialDefinitions { class PartialDefinition extends Expr { - Expr innerDefinedExpr; ControlFlowNode node; PartialDefinition() { - exists(Expr convertedInner | - valueToUpdate(convertedInner, this.getFullyConverted(), node) and - innerDefinedExpr = convertedInner.getUnconverted() and - not this instanceof Conversion - ) + valueToUpdate(_, this.getFullyConverted(), node) and + not this instanceof Conversion } - deprecated predicate partiallyDefines(Variable v) { innerDefinedExpr = v.getAnAccess() } + deprecated predicate partiallyDefines(Variable v) { none() } - deprecated predicate partiallyDefinesThis(ThisExpr e) { innerDefinedExpr = e } + deprecated predicate partiallyDefinesThis(ThisExpr e) { none() } /** * Gets the subBasicBlock where this `PartialDefinition` is defined. @@ -133,10 +130,9 @@ private module PartialDefinitions { * Holds if this `PartialDefinition` defines variable `v` at control-flow * node `cfn`. */ - pragma[noinline] + pragma[noinline] // does this work with a dispred? predicate partiallyDefinesVariableAt(Variable v, ControlFlowNode cfn) { - innerDefinedExpr = v.getAnAccess() and - cfn = node + none() } /** @@ -147,10 +143,7 @@ private module PartialDefinitions { * - `inner` = `... .x`, `outer` = `&...` * - `inner` = `a`, `outer` = `*` */ - predicate definesExpressions(Expr inner, Expr outer) { - inner = innerDefinedExpr and - outer = this - } + predicate definesExpressions(Expr inner, Expr outer) { none() } /** * Gets the location of this element, adjusted to avoid unknown locations @@ -166,6 +159,68 @@ private module PartialDefinitions { } } + class IteratorPartialDefinition extends PartialDefinition { + Variable collection; + Call innerDefinedExpr; + + IteratorPartialDefinition() { + exists(Expr convertedInner | + valueToUpdate(convertedInner, this.getFullyConverted(), node) and + innerDefinedExpr = convertedInner.getUnconverted() and + innerDefinedExpr.getQualifier() = getAnIteratorAccess(collection) and + innerDefinedExpr.getTarget() instanceof IteratorPointerDereferenceMemberOperator + ) + } + + deprecated override predicate partiallyDefines(Variable v) { v = collection } + + deprecated override predicate partiallyDefinesThis(ThisExpr e) { none() } + + override predicate definesExpressions(Expr inner, Expr outer) { + inner = innerDefinedExpr and + outer = this + } + + override predicate partiallyDefinesVariableAt(Variable v, ControlFlowNode cfn) { + v = collection and + cfn = node + } + } + + class VariablePartialDefinition extends PartialDefinition { + Expr innerDefinedExpr; + + VariablePartialDefinition() { + exists(Expr convertedInner | + valueToUpdate(convertedInner, this.getFullyConverted(), node) and + innerDefinedExpr = convertedInner.getUnconverted() and + not this instanceof Conversion + ) + } + + deprecated override predicate partiallyDefines(Variable v) { innerDefinedExpr = v.getAnAccess() } + + deprecated override predicate partiallyDefinesThis(ThisExpr e) { innerDefinedExpr = e } + + /** + * Holds if this partial definition may modify `inner` (or what it points + * to) through `outer`. These expressions will never be `Conversion`s. + * + * For example, in `f(& (*a).x)`, there are two results: + * - `inner` = `... .x`, `outer` = `&...` + * - `inner` = `a`, `outer` = `*` + */ + override predicate definesExpressions(Expr inner, Expr outer) { + inner = innerDefinedExpr and + outer = this + } + + override predicate partiallyDefinesVariableAt(Variable v, ControlFlowNode cfn) { + innerDefinedExpr = v.getAnAccess() and + cfn = node + } + } + /** * A partial definition that's a definition by reference. */ @@ -686,9 +741,7 @@ module FlowVar_internal { * `node instanceof Initializer` is covered by `initializer` instead of this * predicate. */ - predicate assignmentLikeOperation( - ControlFlowNode node, Variable v, Expr assignedExpr - ) { + predicate assignmentLikeOperation(ControlFlowNode node, Variable v, Expr assignedExpr) { // Together, the two following cases cover `Assignment` node = any(AssignExpr ae | @@ -715,6 +768,15 @@ module FlowVar_internal { ) } + Expr getAnIteratorAccess(Variable collection) { + exists(Call c, SsaDefinition def, Variable iterator | + c.getQualifier() = collection.getAnAccess() and + c.getTarget() instanceof BeginOrEndFunction and + def.getAnUltimateDefiningValue(iterator) = c and + result = def.getAUse(iterator) + ) + } + /** * Holds if `v` is initialized to have value `assignedExpr`. */ diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll index c15f39c0c155..c8d963866a11 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll @@ -187,12 +187,6 @@ 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) { @@ -255,28 +249,18 @@ private predicate exprToPartialDefinitionStep(Expr exprIn, Expr exprOut) { exprIn = call.getArgument(argInIndex) ) ) -} - -private predicate isIteratorForCollection(Variable iterator, Variable collection) { - exists(Call beginOrEnd | - beginOrEnd.getTarget() instanceof BeginOrEndFunction and - beginOrEnd.getQualifier() = collection.getAnAccess() and - iterator.getAnAssignedValue() = beginOrEnd + or + exists(Assignment a | + iteratorDereference(exprOut) and + a.getLValue() = exprOut and + a.getRValue() = exprIn ) } -private predicate assignmentViaIterator(Variable iterator, Expr rvalue) { - exists(Assignment a, Call c | - c.getTarget() instanceof IteratorArrayMemberOperator and - c.getQualifier() = iterator.getAnAccess() +private predicate iteratorDereference(Call c) { + c.getTarget() instanceof IteratorArrayMemberOperator or - c.getTarget() instanceof IteratorPointerDereferenceMemberOperator and - c.getQualifier() = iterator.getAnAccess() + c.getTarget() instanceof IteratorPointerDereferenceMemberOperator or - c.getTarget() instanceof IteratorPointerDereferenceOperator and - c.getArgument(0) = iterator.getAnAccess() - | - c = a.getLValue() and - rvalue = a.getRValue() - ) + c.getTarget() instanceof IteratorPointerDereferenceOperator } diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected index 0c0362206e1a..c0f346385545 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected @@ -3176,55 +3176,75 @@ | vector.cpp:329:62:329:65 | iter | vector.cpp:330:3:330:6 | iter | | | vector.cpp:330:2:330:17 | ... = ... | vector.cpp:330:2:330:2 | call to operator* [post update] | | | vector.cpp:330:3:330:6 | iter | vector.cpp:330:2:330:2 | call to operator* | TAINT | +| vector.cpp:330:10:330:15 | call to source | vector.cpp:330:2:330:2 | call to operator* [post update] | TAINT | | vector.cpp:330:10:330:15 | call to source | vector.cpp:330:2:330:17 | ... = ... | | +| vector.cpp:333:38:333:38 | b | vector.cpp:368:5:368:5 | b | | | vector.cpp:334:22:334:24 | call to vector | vector.cpp:336:34:336:35 | v1 | | | vector.cpp:334:22:334:24 | call to vector | vector.cpp:338:7:338:8 | v1 | | -| vector.cpp:334:22:334:24 | call to vector | vector.cpp:354:1:354:1 | v1 | | +| vector.cpp:334:22:334:24 | call to vector | vector.cpp:382:1:382:1 | v1 | | | vector.cpp:334:30:334:32 | call to vector | vector.cpp:340:38:340:39 | v2 | | | vector.cpp:334:30:334:32 | call to vector | vector.cpp:340:56:340:57 | v2 | | | vector.cpp:334:30:334:32 | call to vector | vector.cpp:343:7:343:8 | v2 | | -| vector.cpp:334:30:334:32 | call to vector | vector.cpp:354:1:354:1 | v2 | | +| vector.cpp:334:30:334:32 | call to vector | vector.cpp:382:1:382:1 | v2 | | | vector.cpp:334:38:334:40 | call to vector | vector.cpp:345:15:345:16 | v3 | | | vector.cpp:334:38:334:40 | call to vector | vector.cpp:348:7:348:8 | v3 | | -| vector.cpp:334:38:334:40 | call to vector | vector.cpp:354:1:354:1 | v3 | | +| vector.cpp:334:38:334:40 | call to vector | vector.cpp:382:1:382:1 | v3 | | | vector.cpp:334:46:334:48 | call to vector | vector.cpp:350:38:350:39 | v4 | | | vector.cpp:334:46:334:48 | call to vector | vector.cpp:350:56:350:57 | v4 | | | vector.cpp:334:46:334:48 | call to vector | vector.cpp:353:7:353:8 | v4 | | -| vector.cpp:334:46:334:48 | call to vector | vector.cpp:354:1:354:1 | v4 | | +| vector.cpp:334:46:334:48 | call to vector | vector.cpp:382:1:382:1 | v4 | | +| vector.cpp:334:54:334:56 | call to vector | vector.cpp:355:34:355:35 | v5 | | +| vector.cpp:334:54:334:56 | call to vector | vector.cpp:357:7:357:8 | v5 | | +| vector.cpp:334:54:334:56 | call to vector | vector.cpp:359:7:359:8 | v5 | | +| vector.cpp:334:54:334:56 | call to vector | vector.cpp:382:1:382:1 | v5 | | +| vector.cpp:334:62:334:64 | call to vector | vector.cpp:361:34:361:35 | v6 | | +| vector.cpp:334:62:334:64 | call to vector | vector.cpp:363:7:363:8 | v6 | | +| vector.cpp:334:62:334:64 | call to vector | vector.cpp:364:2:364:3 | v6 | | +| vector.cpp:334:62:334:64 | call to vector | vector.cpp:365:7:365:8 | v6 | | +| vector.cpp:334:62:334:64 | call to vector | vector.cpp:382:1:382:1 | v6 | | +| vector.cpp:334:70:334:72 | call to vector | vector.cpp:367:34:367:35 | v7 | | +| vector.cpp:334:70:334:72 | call to vector | vector.cpp:370:8:370:9 | v7 | | +| vector.cpp:334:70:334:72 | call to vector | vector.cpp:373:8:373:9 | v7 | | +| vector.cpp:334:70:334:72 | call to vector | vector.cpp:375:7:375:8 | v7 | | +| vector.cpp:334:70:334:72 | call to vector | vector.cpp:382:1:382:1 | v7 | | +| vector.cpp:334:78:334:80 | call to vector | vector.cpp:377:34:377:35 | v8 | | +| vector.cpp:334:78:334:80 | call to vector | vector.cpp:379:7:379:8 | v8 | | +| vector.cpp:334:78:334:80 | call to vector | vector.cpp:381:7:381:8 | v8 | | +| vector.cpp:334:78:334:80 | call to vector | vector.cpp:382:1:382:1 | v8 | | | vector.cpp:336:34:336:35 | ref arg v1 | vector.cpp:338:7:338:8 | v1 | | -| vector.cpp:336:34:336:35 | ref arg v1 | vector.cpp:354:1:354:1 | v1 | | +| vector.cpp:336:34:336:35 | ref arg v1 | vector.cpp:382:1:382:1 | v1 | | | vector.cpp:336:34:336:35 | v1 | vector.cpp:336:37:336:41 | call to begin | TAINT | | vector.cpp:336:37:336:41 | call to begin | vector.cpp:337:3:337:4 | i1 | | +| vector.cpp:337:2:337:2 | call to operator* [post update] | vector.cpp:338:7:338:8 | v1 | | +| vector.cpp:337:2:337:2 | call to operator* [post update] | vector.cpp:382:1:382:1 | v1 | | | 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:2 | call to operator* [post update] | 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:338:7:338:8 | ref arg v1 | vector.cpp:382:1:382: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 | | -| vector.cpp:340:38:340:39 | ref arg v2 | vector.cpp:354:1:354:1 | v2 | | +| vector.cpp:340:38:340:39 | ref arg v2 | vector.cpp:382:1:382:1 | v2 | | | vector.cpp:340:38:340:39 | v2 | vector.cpp:340:41:340:45 | call to begin | TAINT | | vector.cpp:340:41:340:45 | call to begin | vector.cpp:340:50:340:51 | it | | | vector.cpp:340:41:340:45 | call to begin | vector.cpp:340:68:340:69 | it | | | vector.cpp:340:41:340:45 | call to begin | vector.cpp:341:4:341:5 | it | | | vector.cpp:340:56:340:57 | ref arg v2 | vector.cpp:340:56:340:57 | v2 | | | vector.cpp:340:56:340:57 | ref arg v2 | vector.cpp:343:7:343:8 | v2 | | -| vector.cpp:340:56:340:57 | ref arg v2 | vector.cpp:354:1:354:1 | v2 | | +| vector.cpp:340:56:340:57 | ref arg v2 | vector.cpp:382:1:382:1 | v2 | | | vector.cpp:340:56:340:57 | v2 | vector.cpp:340:59:340:61 | call to end | TAINT | | vector.cpp:340:68:340:69 | it | vector.cpp:340:66:340:66 | call to operator++ | TAINT | | vector.cpp:340:68:340:69 | ref arg it | vector.cpp:340:50:340:51 | it | | | vector.cpp:340:68:340:69 | ref arg it | vector.cpp:340:68:340:69 | it | | | vector.cpp:340:68:340:69 | ref arg it | vector.cpp:341:4:341:5 | it | | +| vector.cpp:341:3:341:3 | call to operator* [post update] | vector.cpp:340:56:340:57 | v2 | | +| vector.cpp:341:3:341:3 | call to operator* [post update] | vector.cpp:343:7:343:8 | v2 | | +| vector.cpp:341:3:341:3 | call to operator* [post update] | vector.cpp:382:1:382:1 | v2 | | | 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:3 | call to operator* [post update] | 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:343:7:343:8 | ref arg v2 | vector.cpp:382:1:382: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 | | vector.cpp:345:15:345:15 | (__end) | vector.cpp:345:15:345:15 | call to iterator | | @@ -3242,27 +3262,119 @@ | vector.cpp:345:15:345:16 | v3 | vector.cpp:345:15:345:15 | (__range) | | | vector.cpp:345:15:345:16 | v3 | vector.cpp:345:15:345:15 | call to operator* | TAINT | | vector.cpp:346:7:346:12 | call to source | vector.cpp:346:3:346:14 | ... = ... | | -| vector.cpp:348:7:348:8 | ref arg v3 | vector.cpp:354:1:354:1 | v3 | | +| vector.cpp:348:7:348:8 | ref arg v3 | vector.cpp:382:1:382:1 | v3 | | | vector.cpp:350:38:350:39 | ref arg v4 | vector.cpp:350:56:350:57 | v4 | | | vector.cpp:350:38:350:39 | ref arg v4 | vector.cpp:353:7:353:8 | v4 | | -| vector.cpp:350:38:350:39 | ref arg v4 | vector.cpp:354:1:354:1 | v4 | | +| vector.cpp:350:38:350:39 | ref arg v4 | vector.cpp:382:1:382:1 | v4 | | | vector.cpp:350:38:350:39 | v4 | vector.cpp:350:41:350:45 | call to begin | TAINT | | vector.cpp:350:41:350:45 | call to begin | vector.cpp:350:50:350:51 | it | | | vector.cpp:350:41:350:45 | call to begin | vector.cpp:350:68:350:69 | it | | | vector.cpp:350:41:350:45 | call to begin | vector.cpp:351:4:351:5 | it | | | vector.cpp:350:56:350:57 | ref arg v4 | vector.cpp:350:56:350:57 | v4 | | | vector.cpp:350:56:350:57 | ref arg v4 | vector.cpp:353:7:353:8 | v4 | | -| vector.cpp:350:56:350:57 | ref arg v4 | vector.cpp:354:1:354:1 | v4 | | +| vector.cpp:350:56:350:57 | ref arg v4 | vector.cpp:382:1:382:1 | v4 | | | vector.cpp:350:56:350:57 | v4 | vector.cpp:350:59:350:61 | call to end | TAINT | | vector.cpp:350:68:350:69 | it | vector.cpp:350:66:350:66 | call to operator++ | TAINT | | vector.cpp:350:68:350:69 | ref arg it | vector.cpp:350:50:350:51 | it | | | vector.cpp:350:68:350:69 | ref arg it | vector.cpp:350:68:350:69 | it | | | vector.cpp:350:68:350:69 | ref arg it | vector.cpp:351:4:351:5 | it | | +| vector.cpp:351:3:351:3 | call to operator* [post update] | vector.cpp:350:56:350:57 | v4 | | +| vector.cpp:351:3:351:3 | call to operator* [post update] | vector.cpp:353:7:353:8 | v4 | | +| vector.cpp:351:3:351:3 | call to operator* [post update] | vector.cpp:382:1:382:1 | v4 | | | 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:3 | call to operator* [post update] | 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 | | +| vector.cpp:353:7:353:8 | ref arg v4 | vector.cpp:382:1:382:1 | v4 | | +| vector.cpp:355:34:355:35 | ref arg v5 | vector.cpp:357:7:357:8 | v5 | | +| vector.cpp:355:34:355:35 | ref arg v5 | vector.cpp:359:7:359:8 | v5 | | +| vector.cpp:355:34:355:35 | ref arg v5 | vector.cpp:382:1:382:1 | v5 | | +| vector.cpp:355:34:355:35 | v5 | vector.cpp:355:37:355:41 | call to begin | TAINT | +| vector.cpp:355:37:355:41 | call to begin | vector.cpp:356:3:356:4 | i5 | | +| vector.cpp:355:37:355:41 | call to begin | vector.cpp:358:3:358:4 | i5 | | +| vector.cpp:356:2:356:2 | call to operator* [post update] | vector.cpp:357:7:357:8 | v5 | | +| vector.cpp:356:2:356:2 | call to operator* [post update] | vector.cpp:359:7:359:8 | v5 | | +| vector.cpp:356:2:356:2 | call to operator* [post update] | vector.cpp:382:1:382:1 | v5 | | +| vector.cpp:356:2:356:15 | ... = ... | vector.cpp:356:2:356:2 | call to operator* [post update] | | +| vector.cpp:356:3:356:4 | i5 | vector.cpp:356:2:356:2 | call to operator* | TAINT | +| vector.cpp:356:8:356:13 | call to source | vector.cpp:356:2:356:2 | call to operator* [post update] | TAINT | +| vector.cpp:356:8:356:13 | call to source | vector.cpp:356:2:356:15 | ... = ... | | +| vector.cpp:357:7:357:8 | ref arg v5 | vector.cpp:359:7:359:8 | v5 | | +| vector.cpp:357:7:357:8 | ref arg v5 | vector.cpp:382:1:382:1 | v5 | | +| vector.cpp:358:2:358:2 | call to operator* [post update] | vector.cpp:359:7:359:8 | v5 | | +| vector.cpp:358:2:358:2 | call to operator* [post update] | vector.cpp:382:1:382:1 | v5 | | +| vector.cpp:358:2:358:8 | ... = ... | vector.cpp:358:2:358:2 | call to operator* [post update] | | +| vector.cpp:358:3:358:4 | i5 | vector.cpp:358:2:358:2 | call to operator* | TAINT | +| vector.cpp:358:8:358:8 | 1 | vector.cpp:358:2:358:2 | call to operator* [post update] | TAINT | +| vector.cpp:358:8:358:8 | 1 | vector.cpp:358:2:358:8 | ... = ... | | +| vector.cpp:359:7:359:8 | ref arg v5 | vector.cpp:382:1:382:1 | v5 | | +| vector.cpp:361:34:361:35 | ref arg v6 | vector.cpp:363:7:363:8 | v6 | | +| vector.cpp:361:34:361:35 | ref arg v6 | vector.cpp:364:2:364:3 | v6 | | +| vector.cpp:361:34:361:35 | ref arg v6 | vector.cpp:365:7:365:8 | v6 | | +| vector.cpp:361:34:361:35 | ref arg v6 | vector.cpp:382:1:382:1 | v6 | | +| vector.cpp:361:34:361:35 | v6 | vector.cpp:361:37:361:41 | call to begin | TAINT | +| vector.cpp:361:37:361:41 | call to begin | vector.cpp:362:3:362:4 | i6 | | +| vector.cpp:362:2:362:2 | call to operator* [post update] | vector.cpp:363:7:363:8 | v6 | | +| vector.cpp:362:2:362:2 | call to operator* [post update] | vector.cpp:364:2:364:3 | v6 | | +| vector.cpp:362:2:362:2 | call to operator* [post update] | vector.cpp:365:7:365:8 | v6 | | +| vector.cpp:362:2:362:2 | call to operator* [post update] | vector.cpp:382:1:382:1 | v6 | | +| vector.cpp:362:2:362:15 | ... = ... | vector.cpp:362:2:362:2 | call to operator* [post update] | | +| vector.cpp:362:3:362:4 | i6 | vector.cpp:362:2:362:2 | call to operator* | TAINT | +| vector.cpp:362:8:362:13 | call to source | vector.cpp:362:2:362:2 | call to operator* [post update] | TAINT | +| vector.cpp:362:8:362:13 | call to source | vector.cpp:362:2:362:15 | ... = ... | | +| vector.cpp:363:7:363:8 | ref arg v6 | vector.cpp:364:2:364:3 | v6 | | +| vector.cpp:363:7:363:8 | ref arg v6 | vector.cpp:365:7:365:8 | v6 | | +| vector.cpp:363:7:363:8 | ref arg v6 | vector.cpp:382:1:382:1 | v6 | | +| vector.cpp:364:2:364:3 | ref arg v6 | vector.cpp:365:7:365:8 | v6 | | +| vector.cpp:364:2:364:3 | ref arg v6 | vector.cpp:382:1:382:1 | v6 | | +| vector.cpp:364:7:364:26 | call to vector | vector.cpp:364:2:364:3 | ref arg v6 | TAINT | +| vector.cpp:364:7:364:26 | call to vector | vector.cpp:364:5:364:5 | call to operator= | TAINT | +| vector.cpp:365:7:365:8 | ref arg v6 | vector.cpp:382:1:382:1 | v6 | | +| vector.cpp:367:34:367:35 | ref arg v7 | vector.cpp:370:8:370:9 | v7 | | +| vector.cpp:367:34:367:35 | ref arg v7 | vector.cpp:373:8:373:9 | v7 | | +| vector.cpp:367:34:367:35 | ref arg v7 | vector.cpp:375:7:375:8 | v7 | | +| vector.cpp:367:34:367:35 | ref arg v7 | vector.cpp:382:1:382:1 | v7 | | +| vector.cpp:367:34:367:35 | v7 | vector.cpp:367:37:367:41 | call to begin | TAINT | +| vector.cpp:367:37:367:41 | call to begin | vector.cpp:369:4:369:5 | i7 | | +| vector.cpp:367:37:367:41 | call to begin | vector.cpp:372:4:372:5 | i7 | | +| vector.cpp:369:3:369:3 | call to operator* [post update] | vector.cpp:370:8:370:9 | v7 | | +| vector.cpp:369:3:369:3 | call to operator* [post update] | vector.cpp:375:7:375:8 | v7 | | +| vector.cpp:369:3:369:3 | call to operator* [post update] | vector.cpp:382:1:382:1 | v7 | | +| vector.cpp:369:3:369:16 | ... = ... | vector.cpp:369:3:369:3 | call to operator* [post update] | | +| vector.cpp:369:4:369:5 | i7 | vector.cpp:369:3:369:3 | call to operator* | TAINT | +| vector.cpp:369:9:369:14 | call to source | vector.cpp:369:3:369:3 | call to operator* [post update] | TAINT | +| vector.cpp:369:9:369:14 | call to source | vector.cpp:369:3:369:16 | ... = ... | | +| vector.cpp:370:8:370:9 | ref arg v7 | vector.cpp:375:7:375:8 | v7 | | +| vector.cpp:370:8:370:9 | ref arg v7 | vector.cpp:382:1:382:1 | v7 | | +| vector.cpp:372:3:372:3 | call to operator* [post update] | vector.cpp:373:8:373:9 | v7 | | +| vector.cpp:372:3:372:3 | call to operator* [post update] | vector.cpp:375:7:375:8 | v7 | | +| vector.cpp:372:3:372:3 | call to operator* [post update] | vector.cpp:382:1:382:1 | v7 | | +| vector.cpp:372:3:372:9 | ... = ... | vector.cpp:372:3:372:3 | call to operator* [post update] | | +| vector.cpp:372:4:372:5 | i7 | vector.cpp:372:3:372:3 | call to operator* | TAINT | +| vector.cpp:372:9:372:9 | 1 | vector.cpp:372:3:372:3 | call to operator* [post update] | TAINT | +| vector.cpp:372:9:372:9 | 1 | vector.cpp:372:3:372:9 | ... = ... | | +| vector.cpp:373:8:373:9 | ref arg v7 | vector.cpp:375:7:375:8 | v7 | | +| vector.cpp:373:8:373:9 | ref arg v7 | vector.cpp:382:1:382:1 | v7 | | +| vector.cpp:375:7:375:8 | ref arg v7 | vector.cpp:382:1:382:1 | v7 | | +| vector.cpp:377:34:377:35 | ref arg v8 | vector.cpp:379:7:379:8 | v8 | | +| vector.cpp:377:34:377:35 | ref arg v8 | vector.cpp:381:7:381:8 | v8 | | +| vector.cpp:377:34:377:35 | ref arg v8 | vector.cpp:382:1:382:1 | v8 | | +| vector.cpp:377:34:377:35 | v8 | vector.cpp:377:37:377:41 | call to begin | TAINT | +| vector.cpp:377:37:377:41 | call to begin | vector.cpp:378:3:378:4 | i8 | | +| vector.cpp:377:37:377:41 | call to begin | vector.cpp:380:3:380:4 | i8 | | +| vector.cpp:378:2:378:2 | call to operator* [post update] | vector.cpp:379:7:379:8 | v8 | | +| vector.cpp:378:2:378:2 | call to operator* [post update] | vector.cpp:381:7:381:8 | v8 | | +| vector.cpp:378:2:378:2 | call to operator* [post update] | vector.cpp:382:1:382:1 | v8 | | +| vector.cpp:378:2:378:15 | ... = ... | vector.cpp:378:2:378:2 | call to operator* [post update] | | +| vector.cpp:378:3:378:4 | i8 | vector.cpp:378:2:378:2 | call to operator* | TAINT | +| vector.cpp:378:8:378:13 | call to source | vector.cpp:378:2:378:2 | call to operator* [post update] | TAINT | +| vector.cpp:378:8:378:13 | call to source | vector.cpp:378:2:378:15 | ... = ... | | +| vector.cpp:379:7:379:8 | ref arg v8 | vector.cpp:381:7:381:8 | v8 | | +| vector.cpp:379:7:379:8 | ref arg v8 | vector.cpp:382:1:382:1 | v8 | | +| vector.cpp:380:2:380:2 | call to operator* [post update] | vector.cpp:381:7:381:8 | v8 | | +| vector.cpp:380:2:380:2 | call to operator* [post update] | vector.cpp:382:1:382:1 | v8 | | +| vector.cpp:380:2:380:8 | ... = ... | vector.cpp:380:2:380:2 | call to operator* [post update] | | +| vector.cpp:380:3:380:4 | i8 | vector.cpp:380:2:380:2 | call to operator* | TAINT | +| vector.cpp:380:8:380:8 | 1 | vector.cpp:380:2:380:2 | call to operator* [post update] | TAINT | +| vector.cpp:380:8:380:8 | 1 | vector.cpp:380:2:380:8 | ... = ... | | +| vector.cpp:381:7:381:8 | ref arg v8 | vector.cpp:382:1:382:1 | v8 | | diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected index 6697e57e4a34..c8ed520e6399 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected @@ -329,3 +329,11 @@ | 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 | +| vector.cpp:357:7:357:8 | v5 | vector.cpp:356:8:356:13 | call to source | +| vector.cpp:359:7:359:8 | v5 | vector.cpp:356:8:356:13 | call to source | +| vector.cpp:363:7:363:8 | v6 | vector.cpp:362:8:362:13 | call to source | +| vector.cpp:365:7:365:8 | v6 | vector.cpp:362:8:362:13 | call to source | +| vector.cpp:370:8:370:9 | v7 | vector.cpp:369:9:369:14 | call to source | +| vector.cpp:375:7:375:8 | v7 | vector.cpp:369:9:369:14 | call to source | +| vector.cpp:379:7:379:8 | v8 | vector.cpp:378:8:378:13 | call to source | +| vector.cpp:381:7:381:8 | v8 | vector.cpp:378:8:378:13 | call to source | diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected index 7533d079093c..94f4cf9d2fed 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected @@ -278,3 +278,11 @@ | 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 | +| vector.cpp:357:7:357:8 | vector.cpp:356:8:356:13 | AST only | +| vector.cpp:359:7:359:8 | vector.cpp:356:8:356:13 | AST only | +| vector.cpp:363:7:363:8 | vector.cpp:362:8:362:13 | AST only | +| vector.cpp:365:7:365:8 | vector.cpp:362:8:362:13 | AST only | +| vector.cpp:370:8:370:9 | vector.cpp:369:9:369:14 | AST only | +| vector.cpp:375:7:375:8 | vector.cpp:369:9:369:14 | AST only | +| vector.cpp:379:7:379:8 | vector.cpp:378:8:378:13 | AST only | +| vector.cpp:381:7:381:8 | vector.cpp:378:8:378:13 | AST only | diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp index f1cf4e914577..35145c3d815f 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp @@ -330,8 +330,8 @@ void taint_vector_output_iterator(std::vector::iterator iter) { *iter = source(); } -void test_vector_output_iterator() { - std::vector v1(10), v2(10), v3(10), v4(10); +void test_vector_output_iterator(int b) { + std::vector v1(10), v2(10), v3(10), v4(10), v5(10), v6(10), v7(10), v8(10); std::vector::iterator i1 = v1.begin(); *i1 = source(); @@ -351,4 +351,32 @@ void test_vector_output_iterator() { *it = source(); } sink(v4); // tainted [NOT DETECTED by IR] + + std::vector::iterator i5 = v5.begin(); + *i5 = source(); + sink(v5); // tainted [NOT DETECTED by IR] + *i5 = 1; + sink(v5); // tainted [NOT DETECTED by IR] + + std::vector::iterator i6 = v6.begin(); + *i6 = source(); + sink(v6); // tainted [NOT DETECTED by IR] + v6 = std::vector(10); + sink(v6); // [FALSE POSITIVE in AST] + + std::vector::iterator i7 = v7.begin(); + if(b) { + *i7 = source(); + sink(v7); // tainted [NOT DETECTED by IR] + } else { + *i7 = 1; + sink(v7); + } + sink(v7); // tainted [NOT DETECTED by IR] + + std::vector::iterator i8 = v8.begin(); + *i8 = source(); + sink(v8); // tainted [NOT DETECTED by IR] + *i8 = 1; + sink(v8); } From 2e187a51ae6db786322ed979e6fa449e494352a7 Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Wed, 9 Sep 2020 12:45:06 -0700 Subject: [PATCH 06/25] C++: test for interprocedurl iterator flow --- .../dataflow/taint-tests/localTaint.expected | 12 +++--------- .../dataflow/taint-tests/taint.expected | 1 - .../dataflow/taint-tests/test_diff.expected | 1 - .../library-tests/dataflow/taint-tests/vector.cpp | 2 +- 4 files changed, 4 insertions(+), 12 deletions(-) diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected index c0f346385545..13d38363b35c 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected @@ -3269,7 +3269,7 @@ | vector.cpp:350:38:350:39 | v4 | vector.cpp:350:41:350:45 | call to begin | TAINT | | vector.cpp:350:41:350:45 | call to begin | vector.cpp:350:50:350:51 | it | | | vector.cpp:350:41:350:45 | call to begin | vector.cpp:350:68:350:69 | it | | -| vector.cpp:350:41:350:45 | call to begin | vector.cpp:351:4:351:5 | it | | +| vector.cpp:350:41:350:45 | call to begin | vector.cpp:351:32:351:33 | it | | | vector.cpp:350:56:350:57 | ref arg v4 | vector.cpp:350:56:350:57 | v4 | | | vector.cpp:350:56:350:57 | ref arg v4 | vector.cpp:353:7:353:8 | v4 | | | vector.cpp:350:56:350:57 | ref arg v4 | vector.cpp:382:1:382:1 | v4 | | @@ -3277,14 +3277,8 @@ | vector.cpp:350:68:350:69 | it | vector.cpp:350:66:350:66 | call to operator++ | TAINT | | vector.cpp:350:68:350:69 | ref arg it | vector.cpp:350:50:350:51 | it | | | vector.cpp:350:68:350:69 | ref arg it | vector.cpp:350:68:350:69 | it | | -| vector.cpp:350:68:350:69 | ref arg it | vector.cpp:351:4:351:5 | it | | -| vector.cpp:351:3:351:3 | call to operator* [post update] | vector.cpp:350:56:350:57 | v4 | | -| vector.cpp:351:3:351:3 | call to operator* [post update] | vector.cpp:353:7:353:8 | v4 | | -| vector.cpp:351:3:351:3 | call to operator* [post update] | vector.cpp:382:1:382:1 | v4 | | -| 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:351:3:351:3 | call to operator* [post update] | TAINT | -| vector.cpp:351:9:351:14 | call to source | vector.cpp:351:3:351:16 | ... = ... | | +| vector.cpp:350:68:350:69 | ref arg it | vector.cpp:351:32:351:33 | it | | +| vector.cpp:351:32:351:33 | it | vector.cpp:351:32:351:33 | call to iterator | | | vector.cpp:353:7:353:8 | ref arg v4 | vector.cpp:382:1:382:1 | v4 | | | vector.cpp:355:34:355:35 | ref arg v5 | vector.cpp:357:7:357:8 | v5 | | | vector.cpp:355:34:355:35 | ref arg v5 | vector.cpp:359:7:359:8 | v5 | | diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected index c8ed520e6399..6759dd90d60d 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected @@ -328,7 +328,6 @@ | 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 | | vector.cpp:357:7:357:8 | v5 | vector.cpp:356:8:356:13 | call to source | | vector.cpp:359:7:359:8 | v5 | vector.cpp:356:8:356:13 | call to source | | vector.cpp:363:7:363:8 | v6 | vector.cpp:362:8:362:13 | call to source | diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected index 94f4cf9d2fed..8fbeb0c246c5 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected @@ -277,7 +277,6 @@ | 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 | | vector.cpp:357:7:357:8 | vector.cpp:356:8:356:13 | AST only | | vector.cpp:359:7:359:8 | vector.cpp:356:8:356:13 | AST only | | vector.cpp:363:7:363:8 | vector.cpp:362:8:362:13 | AST only | diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp index 35145c3d815f..153385a202d6 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp @@ -348,7 +348,7 @@ void test_vector_output_iterator(int b) { sink(v3); // tainted [NOT DETECTED] for(std::vector::iterator it = v4.begin(); it != v4.end(); ++it) { - *it = source(); + taint_vector_output_iterator(it); } sink(v4); // tainted [NOT DETECTED by IR] From 10633019a6081ee9b169d3a022d2132789e057af Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Wed, 9 Sep 2020 12:45:17 -0700 Subject: [PATCH 07/25] C++: autoformat --- .../semmle/code/cpp/dataflow/internal/FlowVar.qll | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll index cb2cdd68f082..c69293585431 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll @@ -130,10 +130,9 @@ private module PartialDefinitions { * Holds if this `PartialDefinition` defines variable `v` at control-flow * node `cfn`. */ - pragma[noinline] // does this work with a dispred? - predicate partiallyDefinesVariableAt(Variable v, ControlFlowNode cfn) { - none() - } + // does this work with a dispred? + pragma[noinline] + predicate partiallyDefinesVariableAt(Variable v, ControlFlowNode cfn) { none() } /** * Holds if this partial definition may modify `inner` (or what it points @@ -180,7 +179,7 @@ private module PartialDefinitions { inner = innerDefinedExpr and outer = this } - + override predicate partiallyDefinesVariableAt(Variable v, ControlFlowNode cfn) { v = collection and cfn = node @@ -198,7 +197,9 @@ private module PartialDefinitions { ) } - deprecated override predicate partiallyDefines(Variable v) { innerDefinedExpr = v.getAnAccess() } + deprecated override predicate partiallyDefines(Variable v) { + innerDefinedExpr = v.getAnAccess() + } deprecated override predicate partiallyDefinesThis(ThisExpr e) { innerDefinedExpr = e } @@ -214,7 +215,7 @@ private module PartialDefinitions { inner = innerDefinedExpr and outer = this } - + override predicate partiallyDefinesVariableAt(Variable v, ControlFlowNode cfn) { innerDefinedExpr = v.getAnAccess() and cfn = node From 5f2cafc4f5571f06928b43cbb37d97b5a7044640 Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Mon, 14 Sep 2020 14:36:19 -0700 Subject: [PATCH 08/25] C++: Interprocedural iterator flow --- .../code/cpp/dataflow/internal/FlowVar.qll | 43 ++++++++++++++++--- .../dataflow/taint-tests/localTaint.expected | 17 ++++++++ .../dataflow/taint-tests/taint.expected | 1 + .../dataflow/taint-tests/test_diff.expected | 1 + 4 files changed, 56 insertions(+), 6 deletions(-) diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll index c69293585431..0163d1e0ce7c 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll @@ -109,11 +109,10 @@ class FlowVar extends TFlowVar { * ``` */ private module PartialDefinitions { - class PartialDefinition extends Expr { + abstract class PartialDefinition extends Expr { ControlFlowNode node; PartialDefinition() { - valueToUpdate(_, this.getFullyConverted(), node) and not this instanceof Conversion } @@ -160,14 +159,39 @@ private module PartialDefinitions { class IteratorPartialDefinition extends PartialDefinition { Variable collection; - Call innerDefinedExpr; + Expr innerDefinedExpr; IteratorPartialDefinition() { exists(Expr convertedInner | valueToUpdate(convertedInner, this.getFullyConverted(), node) and innerDefinedExpr = convertedInner.getUnconverted() and - innerDefinedExpr.getQualifier() = getAnIteratorAccess(collection) and - innerDefinedExpr.getTarget() instanceof IteratorPointerDereferenceMemberOperator + ( + innerDefinedExpr.(Call).getQualifier() = getAnIteratorAccess(collection) + or + innerDefinedExpr.(Call).getQualifier() = collection.getAnAccess() and + collection instanceof IteratorParameter + ) and + innerDefinedExpr.(Call).getTarget() instanceof IteratorPointerDereferenceMemberOperator + ) + or + // iterators passed by value without a copy constructor + exists(Call call | + call = node and + call.getAnArgument() = innerDefinedExpr and + innerDefinedExpr = this and + this = getAnIteratorAccess(collection) and + not call.getTarget() instanceof IteratorPointerDereferenceMemberOperator + ) + or + // iterators passed by value with a copy constructor + exists(Call call, ConstructorCall copy | + copy.getTarget() instanceof CopyConstructor and + call = node and + call.getAnArgument() = copy and + copy.getArgument(0) = getAnIteratorAccess(collection) and + innerDefinedExpr = this and + this = copy and + not call.getTarget() instanceof IteratorPointerDereferenceMemberOperator ) } @@ -267,7 +291,8 @@ module FlowVar_internal { // The SSA library has a theoretically accurate treatment of reference types, // treating them as immutable, but for data flow it gives better results in // practice to make the variable synonymous with its contents. - not v.getUnspecifiedType() instanceof ReferenceType + not v.getUnspecifiedType() instanceof ReferenceType and + not v instanceof IteratorParameter } /** @@ -616,6 +641,8 @@ module FlowVar_internal { refType = p.getUnderlyingType() and not refType.getBaseType().isConst() ) + or + p instanceof IteratorParameter } /** @@ -778,6 +805,10 @@ module FlowVar_internal { ) } + class IteratorParameter extends Parameter { + IteratorParameter() { this.getUnspecifiedType() instanceof Iterator } + } + /** * Holds if `v` is initialized to have value `assignedExpr`. */ diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected index 13d38363b35c..396fecf212f1 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected @@ -439,23 +439,29 @@ | movableclass.cpp:65:13:65:18 | call to source | movableclass.cpp:65:13:65:20 | call to MyMovableClass | TAINT | | movableclass.cpp:65:13:65:20 | call to MyMovableClass | movableclass.cpp:65:8:65:9 | ref arg s3 | TAINT | | movableclass.cpp:65:13:65:20 | call to MyMovableClass | movableclass.cpp:65:11:65:11 | call to operator= | TAINT | +| standalone_iterators.cpp:39:45:39:51 | source1 | standalone_iterators.cpp:39:45:39:51 | source1 | | | standalone_iterators.cpp:39:45:39:51 | source1 | standalone_iterators.cpp:40:11:40:17 | source1 | | | standalone_iterators.cpp:39:45:39:51 | source1 | standalone_iterators.cpp:41:12:41:18 | source1 | | | standalone_iterators.cpp:39:45:39:51 | source1 | standalone_iterators.cpp:42:14:42:20 | source1 | | | standalone_iterators.cpp:40:11:40:17 | source1 | standalone_iterators.cpp:40:10:40:10 | call to operator* | TAINT | +| standalone_iterators.cpp:41:12:41:18 | ref arg source1 | standalone_iterators.cpp:39:45:39:51 | source1 | | | standalone_iterators.cpp:41:12:41:18 | ref arg source1 | standalone_iterators.cpp:42:14:42:20 | source1 | | | standalone_iterators.cpp:41:12:41:18 | source1 | standalone_iterators.cpp:41:19:41:19 | call to operator++ | TAINT | | standalone_iterators.cpp:41:19:41:19 | call to operator++ | standalone_iterators.cpp:41:10:41:10 | call to operator* | TAINT | | standalone_iterators.cpp:42:12:42:12 | call to operator++ | standalone_iterators.cpp:42:10:42:10 | call to operator* | TAINT | +| standalone_iterators.cpp:42:14:42:20 | ref arg source1 | standalone_iterators.cpp:39:45:39:51 | source1 | | | standalone_iterators.cpp:42:14:42:20 | source1 | standalone_iterators.cpp:42:12:42:12 | call to operator++ | TAINT | +| standalone_iterators.cpp:45:39:45:45 | source1 | standalone_iterators.cpp:45:39:45:45 | source1 | | | standalone_iterators.cpp:45:39:45:45 | source1 | standalone_iterators.cpp:46:11:46:17 | source1 | | | standalone_iterators.cpp:45:39:45:45 | source1 | standalone_iterators.cpp:47:12:47:18 | source1 | | | standalone_iterators.cpp:45:39:45:45 | source1 | standalone_iterators.cpp:48:14:48:20 | source1 | | | standalone_iterators.cpp:46:11:46:17 | source1 | standalone_iterators.cpp:46:10:46:10 | call to operator* | TAINT | +| standalone_iterators.cpp:47:12:47:18 | ref arg source1 | standalone_iterators.cpp:45:39:45:45 | source1 | | | standalone_iterators.cpp:47:12:47:18 | ref arg source1 | standalone_iterators.cpp:48:14:48:20 | source1 | | | standalone_iterators.cpp:47:12:47:18 | source1 | standalone_iterators.cpp:47:19:47:19 | call to operator++ | TAINT | | standalone_iterators.cpp:47:19:47:19 | call to operator++ | standalone_iterators.cpp:47:10:47:10 | call to operator* | TAINT | | standalone_iterators.cpp:48:12:48:12 | call to operator++ | standalone_iterators.cpp:48:10:48:10 | call to operator* | TAINT | +| standalone_iterators.cpp:48:14:48:20 | ref arg source1 | standalone_iterators.cpp:45:39:45:45 | source1 | | | standalone_iterators.cpp:48:14:48:20 | source1 | standalone_iterators.cpp:48:12:48:12 | call to operator++ | TAINT | | standalone_iterators.cpp:51:37:51:43 | source1 | standalone_iterators.cpp:52:11:52:17 | source1 | | | standalone_iterators.cpp:51:37:51:43 | source1 | standalone_iterators.cpp:53:12:53:18 | source1 | | @@ -2967,10 +2973,13 @@ | vector.cpp:255:3:255:4 | ref arg v6 | vector.cpp:262:2:262:2 | v6 | | | vector.cpp:255:13:255:14 | call to iterator | vector.cpp:255:3:255:4 | ref arg v6 | TAINT | | vector.cpp:255:13:255:14 | i1 | vector.cpp:255:13:255:14 | call to iterator | | +| vector.cpp:255:13:255:14 | ref arg call to iterator | vector.cpp:277:1:277:1 | v3 | | +| vector.cpp:255:13:255:14 | ref arg i1 | vector.cpp:277:1:277:1 | v3 | | | vector.cpp:255:17:255:18 | call to iterator | vector.cpp:255:3:255:4 | ref arg v6 | TAINT | | vector.cpp:255:17:255:18 | i2 | vector.cpp:255:17:255:18 | call to iterator | | | vector.cpp:257:8:257:9 | ref arg v4 | vector.cpp:262:2:262:2 | v4 | | | vector.cpp:258:8:258:9 | ref arg v5 | vector.cpp:262:2:262:2 | v5 | | +| vector.cpp:259:8:259:9 | ref arg i1 | vector.cpp:277:1:277:1 | v3 | | | vector.cpp:261:8:261:9 | ref arg v6 | vector.cpp:262:2:262:2 | v6 | | | vector.cpp:265:22:265:23 | call to vector | vector.cpp:269:3:269:4 | v7 | | | vector.cpp:265:22:265:23 | call to vector | vector.cpp:273:8:273:9 | v7 | | @@ -3173,7 +3182,9 @@ | vector.cpp:324:7:324:8 | ref arg v2 | vector.cpp:327:1:327:1 | v2 | | | vector.cpp:325:7:325:8 | ref arg v3 | vector.cpp:327:1:327:1 | v3 | | | vector.cpp:326:7:326:8 | ref arg v4 | vector.cpp:327:1:327:1 | v4 | | +| vector.cpp:329:62:329:65 | iter | vector.cpp:329:62:329:65 | iter | | | vector.cpp:329:62:329:65 | iter | vector.cpp:330:3:330:6 | iter | | +| vector.cpp:330:2:330:2 | call to operator* [post update] | vector.cpp:329:62:329:65 | iter | | | vector.cpp:330:2:330:17 | ... = ... | vector.cpp:330:2:330:2 | call to operator* [post update] | | | vector.cpp:330:3:330:6 | iter | vector.cpp:330:2:330:2 | call to operator* | TAINT | | vector.cpp:330:10:330:15 | call to source | vector.cpp:330:2:330:2 | call to operator* [post update] | TAINT | @@ -3279,6 +3290,12 @@ | vector.cpp:350:68:350:69 | ref arg it | vector.cpp:350:68:350:69 | it | | | vector.cpp:350:68:350:69 | ref arg it | vector.cpp:351:32:351:33 | it | | | vector.cpp:351:32:351:33 | it | vector.cpp:351:32:351:33 | call to iterator | | +| vector.cpp:351:32:351:33 | ref arg call to iterator | vector.cpp:350:56:350:57 | v4 | | +| vector.cpp:351:32:351:33 | ref arg call to iterator | vector.cpp:353:7:353:8 | v4 | | +| vector.cpp:351:32:351:33 | ref arg call to iterator | vector.cpp:382:1:382:1 | v4 | | +| vector.cpp:351:32:351:33 | ref arg it | vector.cpp:350:56:350:57 | v4 | | +| vector.cpp:351:32:351:33 | ref arg it | vector.cpp:353:7:353:8 | v4 | | +| vector.cpp:351:32:351:33 | ref arg it | vector.cpp:382:1:382:1 | v4 | | | vector.cpp:353:7:353:8 | ref arg v4 | vector.cpp:382:1:382:1 | v4 | | | vector.cpp:355:34:355:35 | ref arg v5 | vector.cpp:357:7:357:8 | v5 | | | vector.cpp:355:34:355:35 | ref arg v5 | vector.cpp:359:7:359:8 | v5 | | diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected index 6759dd90d60d..889e1da17e69 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected @@ -328,6 +328,7 @@ | 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:330:10:330:15 | call to source | | vector.cpp:357:7:357:8 | v5 | vector.cpp:356:8:356:13 | call to source | | vector.cpp:359:7:359:8 | v5 | vector.cpp:356:8:356:13 | call to source | | vector.cpp:363:7:363:8 | v6 | vector.cpp:362:8:362:13 | call to source | diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected index 8fbeb0c246c5..0f6b7a574a53 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected @@ -277,6 +277,7 @@ | 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:330:10:330:15 | AST only | | vector.cpp:357:7:357:8 | vector.cpp:356:8:356:13 | AST only | | vector.cpp:359:7:359:8 | vector.cpp:356:8:356:13 | AST only | | vector.cpp:363:7:363:8 | vector.cpp:362:8:362:13 | AST only | From fa0e27b2de6c9fa8d9fbe500b4ba7accda8b0cbe Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Wed, 16 Sep 2020 12:34:52 -0700 Subject: [PATCH 09/25] C++: move interprocedural iterator flow to taint --- .../code/cpp/dataflow/internal/DataFlowUtil.qll | 6 +++--- .../semmle/code/cpp/dataflow/internal/FlowVar.qll | 12 ++++++++---- .../cpp/dataflow/internal/TaintTrackingUtil.qll | 15 ++++++++++----- .../library-tests/dataflow/taint-tests/vector.cpp | 9 ++++++++- 4 files changed, 29 insertions(+), 13 deletions(-) diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll index 9705ca492ce9..1103e50ce16a 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll @@ -303,7 +303,7 @@ private class VariablePartialDefinitionNode extends PartialDefinitionNode { override Node getPreUpdateNode() { pd.definesExpressions(_, result.asExpr()) } } -private class IteratorPartialDefinitionNode extends PartialDefinitionNode { +class IteratorPartialDefinitionNode extends PartialDefinitionNode { override IteratorPartialDefinition pd; override Node getPreUpdateNode() { pd.definesExpressions(_, result.asExpr()) } @@ -546,10 +546,10 @@ predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) { or // In `f(&x->a)`, this step provides the flow from post-`&` to post-`x->a`, // from which there is field flow to `x` via reverse read. - exists(PartialDefinition def, Expr inner, Expr outer | + exists(VariablePartialDefinition def, Expr inner, Expr outer | def.definesExpressions(inner, outer) and inner = nodeTo.(InnerPartialDefinitionNode).getPreUpdateNode().asExpr() and - outer = nodeFrom.(PartialDefinitionNode).getPreUpdateNode().asExpr() + outer = nodeFrom.(VariablePartialDefinitionNode).getPreUpdateNode().asExpr() ) or // Reverse flow: data that flows from the post-update node of a reference diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll index 0163d1e0ce7c..d4c264184d74 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll @@ -109,7 +109,7 @@ class FlowVar extends TFlowVar { * ``` */ private module PartialDefinitions { - abstract class PartialDefinition extends Expr { + class PartialDefinition extends Expr { ControlFlowNode node; PartialDefinition() { @@ -216,8 +216,7 @@ private module PartialDefinitions { VariablePartialDefinition() { exists(Expr convertedInner | valueToUpdate(convertedInner, this.getFullyConverted(), node) and - innerDefinedExpr = convertedInner.getUnconverted() and - not this instanceof Conversion + innerDefinedExpr = convertedInner.getUnconverted() ) } @@ -249,11 +248,16 @@ private module PartialDefinitions { /** * A partial definition that's a definition by reference. */ - class DefinitionByReference extends PartialDefinition { + class DefinitionByReference extends VariablePartialDefinition { DefinitionByReference() { exists(Call c | this = c.getAnArgument() or this = c.getQualifier()) } } } +predicate quickTest(PartialDefinition pd) { + pd instanceof DefinitionByReference and + pd instanceof IteratorPartialDefinition +} + import PartialDefinitions private import FlowVar_internal diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll index c8d963866a11..f52c3cddf7e1 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll @@ -31,6 +31,11 @@ predicate localTaintStep(DataFlow::Node src, DataFlow::Node sink) { */ predicate defaultAdditionalTaintStep(DataFlow::Node src, DataFlow::Node sink) { localAdditionalTaintStep(src, sink) + or + exists(FunctionCall call, int i | + sink.(DataFlow::IteratorPartialDefinitionNode).getPartialDefinition().definesExpressions(_, call.getArgument(i)) and + src.(DataFlow::RefParameterFinalValueNode).getParameter() = call.getTarget().getParameter(i) + ) } /** @@ -258,9 +263,9 @@ private predicate exprToPartialDefinitionStep(Expr exprIn, Expr exprOut) { } private predicate iteratorDereference(Call c) { - c.getTarget() instanceof IteratorArrayMemberOperator - or - c.getTarget() instanceof IteratorPointerDereferenceMemberOperator - or - c.getTarget() instanceof IteratorPointerDereferenceOperator + c.getTarget() instanceof IteratorArrayMemberOperator + or + c.getTarget() instanceof IteratorPointerDereferenceMemberOperator + or + c.getTarget() instanceof IteratorPointerDereferenceOperator } diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp index 153385a202d6..4fc63acbad2f 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp @@ -331,7 +331,7 @@ void taint_vector_output_iterator(std::vector::iterator iter) { } void test_vector_output_iterator(int b) { - std::vector v1(10), v2(10), v3(10), v4(10), v5(10), v6(10), v7(10), v8(10); + std::vector v1(10), v2(10), v3(10), v4(10), v5(10), v6(10), v7(10), v8(10), v9(10); std::vector::iterator i1 = v1.begin(); *i1 = source(); @@ -379,4 +379,11 @@ void test_vector_output_iterator(int b) { sink(v8); // tainted [NOT DETECTED by IR] *i8 = 1; sink(v8); + + std::vector::iterator i9 = v9.begin(); + + *i9 = source(); + taint_vector_output_iterator(i9); + + sink(v9); } From 086d074a26e55d45ff6e7c70a91124eee0c3fac7 Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Wed, 16 Sep 2020 12:48:38 -0700 Subject: [PATCH 10/25] C++: make PartialDefinition abstract --- .../src/semmle/code/cpp/dataflow/internal/FlowVar.qll | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll index d4c264184d74..45a537f80498 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll @@ -109,16 +109,16 @@ class FlowVar extends TFlowVar { * ``` */ private module PartialDefinitions { - class PartialDefinition extends Expr { + abstract class PartialDefinition extends Expr { ControlFlowNode node; PartialDefinition() { not this instanceof Conversion } - deprecated predicate partiallyDefines(Variable v) { none() } + deprecated abstract predicate partiallyDefines(Variable v); - deprecated predicate partiallyDefinesThis(ThisExpr e) { none() } + deprecated abstract predicate partiallyDefinesThis(ThisExpr e); /** * Gets the subBasicBlock where this `PartialDefinition` is defined. @@ -131,7 +131,7 @@ private module PartialDefinitions { */ // does this work with a dispred? pragma[noinline] - predicate partiallyDefinesVariableAt(Variable v, ControlFlowNode cfn) { none() } + abstract predicate partiallyDefinesVariableAt(Variable v, ControlFlowNode cfn); /** * Holds if this partial definition may modify `inner` (or what it points @@ -141,7 +141,7 @@ private module PartialDefinitions { * - `inner` = `... .x`, `outer` = `&...` * - `inner` = `a`, `outer` = `*` */ - predicate definesExpressions(Expr inner, Expr outer) { none() } + abstract predicate definesExpressions(Expr inner, Expr outer); /** * Gets the location of this element, adjusted to avoid unknown locations From 44c5233459a67643a405200398fb5dc70c60fea2 Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Wed, 16 Sep 2020 12:49:15 -0700 Subject: [PATCH 11/25] C++: accept test output --- .../dataflow/taint-tests/localTaint.expected | 116 ++++++++++-------- .../dataflow/taint-tests/taint.expected | 2 + .../dataflow/taint-tests/test_diff.expected | 2 + 3 files changed, 72 insertions(+), 48 deletions(-) diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected index 396fecf212f1..e5e4905e395b 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected @@ -2972,9 +2972,9 @@ | vector.cpp:255:3:255:4 | ref arg v6 | vector.cpp:261:8:261:9 | v6 | | | vector.cpp:255:3:255:4 | ref arg v6 | vector.cpp:262:2:262:2 | v6 | | | vector.cpp:255:13:255:14 | call to iterator | vector.cpp:255:3:255:4 | ref arg v6 | TAINT | +| vector.cpp:255:13:255:14 | call to iterator [post update] | vector.cpp:277:1:277:1 | v3 | | | vector.cpp:255:13:255:14 | i1 | vector.cpp:255:13:255:14 | call to iterator | | -| vector.cpp:255:13:255:14 | ref arg call to iterator | vector.cpp:277:1:277:1 | v3 | | -| vector.cpp:255:13:255:14 | ref arg i1 | vector.cpp:277:1:277:1 | v3 | | +| vector.cpp:255:13:255:14 | i1 [post update] | vector.cpp:277:1:277:1 | v3 | | | vector.cpp:255:17:255:18 | call to iterator | vector.cpp:255:3:255:4 | ref arg v6 | TAINT | | vector.cpp:255:17:255:18 | i2 | vector.cpp:255:17:255:18 | call to iterator | | | vector.cpp:257:8:257:9 | ref arg v4 | vector.cpp:262:2:262:2 | v4 | | @@ -3192,57 +3192,60 @@ | vector.cpp:333:38:333:38 | b | vector.cpp:368:5:368:5 | b | | | vector.cpp:334:22:334:24 | call to vector | vector.cpp:336:34:336:35 | v1 | | | vector.cpp:334:22:334:24 | call to vector | vector.cpp:338:7:338:8 | v1 | | -| vector.cpp:334:22:334:24 | call to vector | vector.cpp:382:1:382:1 | v1 | | +| vector.cpp:334:22:334:24 | call to vector | vector.cpp:389:1:389:1 | v1 | | | vector.cpp:334:30:334:32 | call to vector | vector.cpp:340:38:340:39 | v2 | | | vector.cpp:334:30:334:32 | call to vector | vector.cpp:340:56:340:57 | v2 | | | vector.cpp:334:30:334:32 | call to vector | vector.cpp:343:7:343:8 | v2 | | -| vector.cpp:334:30:334:32 | call to vector | vector.cpp:382:1:382:1 | v2 | | +| vector.cpp:334:30:334:32 | call to vector | vector.cpp:389:1:389:1 | v2 | | | vector.cpp:334:38:334:40 | call to vector | vector.cpp:345:15:345:16 | v3 | | | vector.cpp:334:38:334:40 | call to vector | vector.cpp:348:7:348:8 | v3 | | -| vector.cpp:334:38:334:40 | call to vector | vector.cpp:382:1:382:1 | v3 | | +| vector.cpp:334:38:334:40 | call to vector | vector.cpp:389:1:389:1 | v3 | | | vector.cpp:334:46:334:48 | call to vector | vector.cpp:350:38:350:39 | v4 | | | vector.cpp:334:46:334:48 | call to vector | vector.cpp:350:56:350:57 | v4 | | | vector.cpp:334:46:334:48 | call to vector | vector.cpp:353:7:353:8 | v4 | | -| vector.cpp:334:46:334:48 | call to vector | vector.cpp:382:1:382:1 | v4 | | +| vector.cpp:334:46:334:48 | call to vector | vector.cpp:389:1:389:1 | v4 | | | vector.cpp:334:54:334:56 | call to vector | vector.cpp:355:34:355:35 | v5 | | | vector.cpp:334:54:334:56 | call to vector | vector.cpp:357:7:357:8 | v5 | | | vector.cpp:334:54:334:56 | call to vector | vector.cpp:359:7:359:8 | v5 | | -| vector.cpp:334:54:334:56 | call to vector | vector.cpp:382:1:382:1 | v5 | | +| vector.cpp:334:54:334:56 | call to vector | vector.cpp:389:1:389:1 | v5 | | | vector.cpp:334:62:334:64 | call to vector | vector.cpp:361:34:361:35 | v6 | | | vector.cpp:334:62:334:64 | call to vector | vector.cpp:363:7:363:8 | v6 | | | vector.cpp:334:62:334:64 | call to vector | vector.cpp:364:2:364:3 | v6 | | | vector.cpp:334:62:334:64 | call to vector | vector.cpp:365:7:365:8 | v6 | | -| vector.cpp:334:62:334:64 | call to vector | vector.cpp:382:1:382:1 | v6 | | +| vector.cpp:334:62:334:64 | call to vector | vector.cpp:389:1:389:1 | v6 | | | vector.cpp:334:70:334:72 | call to vector | vector.cpp:367:34:367:35 | v7 | | | vector.cpp:334:70:334:72 | call to vector | vector.cpp:370:8:370:9 | v7 | | | vector.cpp:334:70:334:72 | call to vector | vector.cpp:373:8:373:9 | v7 | | | vector.cpp:334:70:334:72 | call to vector | vector.cpp:375:7:375:8 | v7 | | -| vector.cpp:334:70:334:72 | call to vector | vector.cpp:382:1:382:1 | v7 | | +| vector.cpp:334:70:334:72 | call to vector | vector.cpp:389:1:389:1 | v7 | | | vector.cpp:334:78:334:80 | call to vector | vector.cpp:377:34:377:35 | v8 | | | vector.cpp:334:78:334:80 | call to vector | vector.cpp:379:7:379:8 | v8 | | | vector.cpp:334:78:334:80 | call to vector | vector.cpp:381:7:381:8 | v8 | | -| vector.cpp:334:78:334:80 | call to vector | vector.cpp:382:1:382:1 | v8 | | +| vector.cpp:334:78:334:80 | call to vector | vector.cpp:389:1:389:1 | v8 | | +| vector.cpp:334:86:334:88 | call to vector | vector.cpp:383:34:383:35 | v9 | | +| vector.cpp:334:86:334:88 | call to vector | vector.cpp:388:7:388:8 | v9 | | +| vector.cpp:334:86:334:88 | call to vector | vector.cpp:389:1:389:1 | v9 | | | vector.cpp:336:34:336:35 | ref arg v1 | vector.cpp:338:7:338:8 | v1 | | -| vector.cpp:336:34:336:35 | ref arg v1 | vector.cpp:382:1:382:1 | v1 | | +| vector.cpp:336:34:336:35 | ref arg v1 | vector.cpp:389:1:389:1 | v1 | | | vector.cpp:336:34:336:35 | v1 | vector.cpp:336:37:336:41 | call to begin | TAINT | | vector.cpp:336:37:336:41 | call to begin | vector.cpp:337:3:337:4 | i1 | | | vector.cpp:337:2:337:2 | call to operator* [post update] | vector.cpp:338:7:338:8 | v1 | | -| vector.cpp:337:2:337:2 | call to operator* [post update] | vector.cpp:382:1:382:1 | v1 | | +| vector.cpp:337:2:337:2 | call to operator* [post update] | vector.cpp:389:1:389:1 | v1 | | | 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:337:2:337:2 | call to operator* [post update] | TAINT | | vector.cpp:337:8:337:13 | call to source | vector.cpp:337:2:337:15 | ... = ... | | -| vector.cpp:338:7:338:8 | ref arg v1 | vector.cpp:382:1:382:1 | v1 | | +| vector.cpp:338:7:338:8 | ref arg v1 | vector.cpp:389:1:389: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 | | -| vector.cpp:340:38:340:39 | ref arg v2 | vector.cpp:382:1:382:1 | v2 | | +| vector.cpp:340:38:340:39 | ref arg v2 | vector.cpp:389:1:389:1 | v2 | | | vector.cpp:340:38:340:39 | v2 | vector.cpp:340:41:340:45 | call to begin | TAINT | | vector.cpp:340:41:340:45 | call to begin | vector.cpp:340:50:340:51 | it | | | vector.cpp:340:41:340:45 | call to begin | vector.cpp:340:68:340:69 | it | | | vector.cpp:340:41:340:45 | call to begin | vector.cpp:341:4:341:5 | it | | | vector.cpp:340:56:340:57 | ref arg v2 | vector.cpp:340:56:340:57 | v2 | | | vector.cpp:340:56:340:57 | ref arg v2 | vector.cpp:343:7:343:8 | v2 | | -| vector.cpp:340:56:340:57 | ref arg v2 | vector.cpp:382:1:382:1 | v2 | | +| vector.cpp:340:56:340:57 | ref arg v2 | vector.cpp:389:1:389:1 | v2 | | | vector.cpp:340:56:340:57 | v2 | vector.cpp:340:59:340:61 | call to end | TAINT | | vector.cpp:340:68:340:69 | it | vector.cpp:340:66:340:66 | call to operator++ | TAINT | | vector.cpp:340:68:340:69 | ref arg it | vector.cpp:340:50:340:51 | it | | @@ -3250,12 +3253,12 @@ | vector.cpp:340:68:340:69 | ref arg it | vector.cpp:341:4:341:5 | it | | | vector.cpp:341:3:341:3 | call to operator* [post update] | vector.cpp:340:56:340:57 | v2 | | | vector.cpp:341:3:341:3 | call to operator* [post update] | vector.cpp:343:7:343:8 | v2 | | -| vector.cpp:341:3:341:3 | call to operator* [post update] | vector.cpp:382:1:382:1 | v2 | | +| vector.cpp:341:3:341:3 | call to operator* [post update] | vector.cpp:389:1:389:1 | v2 | | | 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:341:3:341:3 | call to operator* [post update] | TAINT | | vector.cpp:341:9:341:14 | call to source | vector.cpp:341:3:341:16 | ... = ... | | -| vector.cpp:343:7:343:8 | ref arg v2 | vector.cpp:382:1:382:1 | v2 | | +| vector.cpp:343:7:343:8 | ref arg v2 | vector.cpp:389:1:389: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 | | vector.cpp:345:15:345:15 | (__end) | vector.cpp:345:15:345:15 | call to iterator | | @@ -3273,119 +3276,136 @@ | vector.cpp:345:15:345:16 | v3 | vector.cpp:345:15:345:15 | (__range) | | | vector.cpp:345:15:345:16 | v3 | vector.cpp:345:15:345:15 | call to operator* | TAINT | | vector.cpp:346:7:346:12 | call to source | vector.cpp:346:3:346:14 | ... = ... | | -| vector.cpp:348:7:348:8 | ref arg v3 | vector.cpp:382:1:382:1 | v3 | | +| vector.cpp:348:7:348:8 | ref arg v3 | vector.cpp:389:1:389:1 | v3 | | | vector.cpp:350:38:350:39 | ref arg v4 | vector.cpp:350:56:350:57 | v4 | | | vector.cpp:350:38:350:39 | ref arg v4 | vector.cpp:353:7:353:8 | v4 | | -| vector.cpp:350:38:350:39 | ref arg v4 | vector.cpp:382:1:382:1 | v4 | | +| vector.cpp:350:38:350:39 | ref arg v4 | vector.cpp:389:1:389:1 | v4 | | | vector.cpp:350:38:350:39 | v4 | vector.cpp:350:41:350:45 | call to begin | TAINT | | vector.cpp:350:41:350:45 | call to begin | vector.cpp:350:50:350:51 | it | | | vector.cpp:350:41:350:45 | call to begin | vector.cpp:350:68:350:69 | it | | | vector.cpp:350:41:350:45 | call to begin | vector.cpp:351:32:351:33 | it | | | vector.cpp:350:56:350:57 | ref arg v4 | vector.cpp:350:56:350:57 | v4 | | | vector.cpp:350:56:350:57 | ref arg v4 | vector.cpp:353:7:353:8 | v4 | | -| vector.cpp:350:56:350:57 | ref arg v4 | vector.cpp:382:1:382:1 | v4 | | +| vector.cpp:350:56:350:57 | ref arg v4 | vector.cpp:389:1:389:1 | v4 | | | vector.cpp:350:56:350:57 | v4 | vector.cpp:350:59:350:61 | call to end | TAINT | | vector.cpp:350:68:350:69 | it | vector.cpp:350:66:350:66 | call to operator++ | TAINT | | vector.cpp:350:68:350:69 | ref arg it | vector.cpp:350:50:350:51 | it | | | vector.cpp:350:68:350:69 | ref arg it | vector.cpp:350:68:350:69 | it | | | vector.cpp:350:68:350:69 | ref arg it | vector.cpp:351:32:351:33 | it | | +| vector.cpp:351:32:351:33 | call to iterator [post update] | vector.cpp:350:56:350:57 | v4 | | +| vector.cpp:351:32:351:33 | call to iterator [post update] | vector.cpp:353:7:353:8 | v4 | | +| vector.cpp:351:32:351:33 | call to iterator [post update] | vector.cpp:389:1:389:1 | v4 | | | vector.cpp:351:32:351:33 | it | vector.cpp:351:32:351:33 | call to iterator | | -| vector.cpp:351:32:351:33 | ref arg call to iterator | vector.cpp:350:56:350:57 | v4 | | -| vector.cpp:351:32:351:33 | ref arg call to iterator | vector.cpp:353:7:353:8 | v4 | | -| vector.cpp:351:32:351:33 | ref arg call to iterator | vector.cpp:382:1:382:1 | v4 | | -| vector.cpp:351:32:351:33 | ref arg it | vector.cpp:350:56:350:57 | v4 | | -| vector.cpp:351:32:351:33 | ref arg it | vector.cpp:353:7:353:8 | v4 | | -| vector.cpp:351:32:351:33 | ref arg it | vector.cpp:382:1:382:1 | v4 | | -| vector.cpp:353:7:353:8 | ref arg v4 | vector.cpp:382:1:382:1 | v4 | | +| vector.cpp:351:32:351:33 | it [post update] | vector.cpp:350:56:350:57 | v4 | | +| vector.cpp:351:32:351:33 | it [post update] | vector.cpp:353:7:353:8 | v4 | | +| vector.cpp:351:32:351:33 | it [post update] | vector.cpp:389:1:389:1 | v4 | | +| vector.cpp:353:7:353:8 | ref arg v4 | vector.cpp:389:1:389:1 | v4 | | | vector.cpp:355:34:355:35 | ref arg v5 | vector.cpp:357:7:357:8 | v5 | | | vector.cpp:355:34:355:35 | ref arg v5 | vector.cpp:359:7:359:8 | v5 | | -| vector.cpp:355:34:355:35 | ref arg v5 | vector.cpp:382:1:382:1 | v5 | | +| vector.cpp:355:34:355:35 | ref arg v5 | vector.cpp:389:1:389:1 | v5 | | | vector.cpp:355:34:355:35 | v5 | vector.cpp:355:37:355:41 | call to begin | TAINT | | vector.cpp:355:37:355:41 | call to begin | vector.cpp:356:3:356:4 | i5 | | | vector.cpp:355:37:355:41 | call to begin | vector.cpp:358:3:358:4 | i5 | | | vector.cpp:356:2:356:2 | call to operator* [post update] | vector.cpp:357:7:357:8 | v5 | | | vector.cpp:356:2:356:2 | call to operator* [post update] | vector.cpp:359:7:359:8 | v5 | | -| vector.cpp:356:2:356:2 | call to operator* [post update] | vector.cpp:382:1:382:1 | v5 | | +| vector.cpp:356:2:356:2 | call to operator* [post update] | vector.cpp:389:1:389:1 | v5 | | | vector.cpp:356:2:356:15 | ... = ... | vector.cpp:356:2:356:2 | call to operator* [post update] | | | vector.cpp:356:3:356:4 | i5 | vector.cpp:356:2:356:2 | call to operator* | TAINT | | vector.cpp:356:8:356:13 | call to source | vector.cpp:356:2:356:2 | call to operator* [post update] | TAINT | | vector.cpp:356:8:356:13 | call to source | vector.cpp:356:2:356:15 | ... = ... | | | vector.cpp:357:7:357:8 | ref arg v5 | vector.cpp:359:7:359:8 | v5 | | -| vector.cpp:357:7:357:8 | ref arg v5 | vector.cpp:382:1:382:1 | v5 | | +| vector.cpp:357:7:357:8 | ref arg v5 | vector.cpp:389:1:389:1 | v5 | | | vector.cpp:358:2:358:2 | call to operator* [post update] | vector.cpp:359:7:359:8 | v5 | | -| vector.cpp:358:2:358:2 | call to operator* [post update] | vector.cpp:382:1:382:1 | v5 | | +| vector.cpp:358:2:358:2 | call to operator* [post update] | vector.cpp:389:1:389:1 | v5 | | | vector.cpp:358:2:358:8 | ... = ... | vector.cpp:358:2:358:2 | call to operator* [post update] | | | vector.cpp:358:3:358:4 | i5 | vector.cpp:358:2:358:2 | call to operator* | TAINT | | vector.cpp:358:8:358:8 | 1 | vector.cpp:358:2:358:2 | call to operator* [post update] | TAINT | | vector.cpp:358:8:358:8 | 1 | vector.cpp:358:2:358:8 | ... = ... | | -| vector.cpp:359:7:359:8 | ref arg v5 | vector.cpp:382:1:382:1 | v5 | | +| vector.cpp:359:7:359:8 | ref arg v5 | vector.cpp:389:1:389:1 | v5 | | | vector.cpp:361:34:361:35 | ref arg v6 | vector.cpp:363:7:363:8 | v6 | | | vector.cpp:361:34:361:35 | ref arg v6 | vector.cpp:364:2:364:3 | v6 | | | vector.cpp:361:34:361:35 | ref arg v6 | vector.cpp:365:7:365:8 | v6 | | -| vector.cpp:361:34:361:35 | ref arg v6 | vector.cpp:382:1:382:1 | v6 | | +| vector.cpp:361:34:361:35 | ref arg v6 | vector.cpp:389:1:389:1 | v6 | | | vector.cpp:361:34:361:35 | v6 | vector.cpp:361:37:361:41 | call to begin | TAINT | | vector.cpp:361:37:361:41 | call to begin | vector.cpp:362:3:362:4 | i6 | | | vector.cpp:362:2:362:2 | call to operator* [post update] | vector.cpp:363:7:363:8 | v6 | | | vector.cpp:362:2:362:2 | call to operator* [post update] | vector.cpp:364:2:364:3 | v6 | | | vector.cpp:362:2:362:2 | call to operator* [post update] | vector.cpp:365:7:365:8 | v6 | | -| vector.cpp:362:2:362:2 | call to operator* [post update] | vector.cpp:382:1:382:1 | v6 | | +| vector.cpp:362:2:362:2 | call to operator* [post update] | vector.cpp:389:1:389:1 | v6 | | | vector.cpp:362:2:362:15 | ... = ... | vector.cpp:362:2:362:2 | call to operator* [post update] | | | vector.cpp:362:3:362:4 | i6 | vector.cpp:362:2:362:2 | call to operator* | TAINT | | vector.cpp:362:8:362:13 | call to source | vector.cpp:362:2:362:2 | call to operator* [post update] | TAINT | | vector.cpp:362:8:362:13 | call to source | vector.cpp:362:2:362:15 | ... = ... | | | vector.cpp:363:7:363:8 | ref arg v6 | vector.cpp:364:2:364:3 | v6 | | | vector.cpp:363:7:363:8 | ref arg v6 | vector.cpp:365:7:365:8 | v6 | | -| vector.cpp:363:7:363:8 | ref arg v6 | vector.cpp:382:1:382:1 | v6 | | +| vector.cpp:363:7:363:8 | ref arg v6 | vector.cpp:389:1:389:1 | v6 | | | vector.cpp:364:2:364:3 | ref arg v6 | vector.cpp:365:7:365:8 | v6 | | -| vector.cpp:364:2:364:3 | ref arg v6 | vector.cpp:382:1:382:1 | v6 | | +| vector.cpp:364:2:364:3 | ref arg v6 | vector.cpp:389:1:389:1 | v6 | | | vector.cpp:364:7:364:26 | call to vector | vector.cpp:364:2:364:3 | ref arg v6 | TAINT | | vector.cpp:364:7:364:26 | call to vector | vector.cpp:364:5:364:5 | call to operator= | TAINT | -| vector.cpp:365:7:365:8 | ref arg v6 | vector.cpp:382:1:382:1 | v6 | | +| vector.cpp:365:7:365:8 | ref arg v6 | vector.cpp:389:1:389:1 | v6 | | | vector.cpp:367:34:367:35 | ref arg v7 | vector.cpp:370:8:370:9 | v7 | | | vector.cpp:367:34:367:35 | ref arg v7 | vector.cpp:373:8:373:9 | v7 | | | vector.cpp:367:34:367:35 | ref arg v7 | vector.cpp:375:7:375:8 | v7 | | -| vector.cpp:367:34:367:35 | ref arg v7 | vector.cpp:382:1:382:1 | v7 | | +| vector.cpp:367:34:367:35 | ref arg v7 | vector.cpp:389:1:389:1 | v7 | | | vector.cpp:367:34:367:35 | v7 | vector.cpp:367:37:367:41 | call to begin | TAINT | | vector.cpp:367:37:367:41 | call to begin | vector.cpp:369:4:369:5 | i7 | | | vector.cpp:367:37:367:41 | call to begin | vector.cpp:372:4:372:5 | i7 | | | vector.cpp:369:3:369:3 | call to operator* [post update] | vector.cpp:370:8:370:9 | v7 | | | vector.cpp:369:3:369:3 | call to operator* [post update] | vector.cpp:375:7:375:8 | v7 | | -| vector.cpp:369:3:369:3 | call to operator* [post update] | vector.cpp:382:1:382:1 | v7 | | +| vector.cpp:369:3:369:3 | call to operator* [post update] | vector.cpp:389:1:389:1 | v7 | | | vector.cpp:369:3:369:16 | ... = ... | vector.cpp:369:3:369:3 | call to operator* [post update] | | | vector.cpp:369:4:369:5 | i7 | vector.cpp:369:3:369:3 | call to operator* | TAINT | | vector.cpp:369:9:369:14 | call to source | vector.cpp:369:3:369:3 | call to operator* [post update] | TAINT | | vector.cpp:369:9:369:14 | call to source | vector.cpp:369:3:369:16 | ... = ... | | | vector.cpp:370:8:370:9 | ref arg v7 | vector.cpp:375:7:375:8 | v7 | | -| vector.cpp:370:8:370:9 | ref arg v7 | vector.cpp:382:1:382:1 | v7 | | +| vector.cpp:370:8:370:9 | ref arg v7 | vector.cpp:389:1:389:1 | v7 | | | vector.cpp:372:3:372:3 | call to operator* [post update] | vector.cpp:373:8:373:9 | v7 | | | vector.cpp:372:3:372:3 | call to operator* [post update] | vector.cpp:375:7:375:8 | v7 | | -| vector.cpp:372:3:372:3 | call to operator* [post update] | vector.cpp:382:1:382:1 | v7 | | +| vector.cpp:372:3:372:3 | call to operator* [post update] | vector.cpp:389:1:389:1 | v7 | | | vector.cpp:372:3:372:9 | ... = ... | vector.cpp:372:3:372:3 | call to operator* [post update] | | | vector.cpp:372:4:372:5 | i7 | vector.cpp:372:3:372:3 | call to operator* | TAINT | | vector.cpp:372:9:372:9 | 1 | vector.cpp:372:3:372:3 | call to operator* [post update] | TAINT | | vector.cpp:372:9:372:9 | 1 | vector.cpp:372:3:372:9 | ... = ... | | | vector.cpp:373:8:373:9 | ref arg v7 | vector.cpp:375:7:375:8 | v7 | | -| vector.cpp:373:8:373:9 | ref arg v7 | vector.cpp:382:1:382:1 | v7 | | -| vector.cpp:375:7:375:8 | ref arg v7 | vector.cpp:382:1:382:1 | v7 | | +| vector.cpp:373:8:373:9 | ref arg v7 | vector.cpp:389:1:389:1 | v7 | | +| vector.cpp:375:7:375:8 | ref arg v7 | vector.cpp:389:1:389:1 | v7 | | | vector.cpp:377:34:377:35 | ref arg v8 | vector.cpp:379:7:379:8 | v8 | | | vector.cpp:377:34:377:35 | ref arg v8 | vector.cpp:381:7:381:8 | v8 | | -| vector.cpp:377:34:377:35 | ref arg v8 | vector.cpp:382:1:382:1 | v8 | | +| vector.cpp:377:34:377:35 | ref arg v8 | vector.cpp:389:1:389:1 | v8 | | | vector.cpp:377:34:377:35 | v8 | vector.cpp:377:37:377:41 | call to begin | TAINT | | vector.cpp:377:37:377:41 | call to begin | vector.cpp:378:3:378:4 | i8 | | | vector.cpp:377:37:377:41 | call to begin | vector.cpp:380:3:380:4 | i8 | | | vector.cpp:378:2:378:2 | call to operator* [post update] | vector.cpp:379:7:379:8 | v8 | | | vector.cpp:378:2:378:2 | call to operator* [post update] | vector.cpp:381:7:381:8 | v8 | | -| vector.cpp:378:2:378:2 | call to operator* [post update] | vector.cpp:382:1:382:1 | v8 | | +| vector.cpp:378:2:378:2 | call to operator* [post update] | vector.cpp:389:1:389:1 | v8 | | | vector.cpp:378:2:378:15 | ... = ... | vector.cpp:378:2:378:2 | call to operator* [post update] | | | vector.cpp:378:3:378:4 | i8 | vector.cpp:378:2:378:2 | call to operator* | TAINT | | vector.cpp:378:8:378:13 | call to source | vector.cpp:378:2:378:2 | call to operator* [post update] | TAINT | | vector.cpp:378:8:378:13 | call to source | vector.cpp:378:2:378:15 | ... = ... | | | vector.cpp:379:7:379:8 | ref arg v8 | vector.cpp:381:7:381:8 | v8 | | -| vector.cpp:379:7:379:8 | ref arg v8 | vector.cpp:382:1:382:1 | v8 | | +| vector.cpp:379:7:379:8 | ref arg v8 | vector.cpp:389:1:389:1 | v8 | | | vector.cpp:380:2:380:2 | call to operator* [post update] | vector.cpp:381:7:381:8 | v8 | | -| vector.cpp:380:2:380:2 | call to operator* [post update] | vector.cpp:382:1:382:1 | v8 | | +| vector.cpp:380:2:380:2 | call to operator* [post update] | vector.cpp:389:1:389:1 | v8 | | | vector.cpp:380:2:380:8 | ... = ... | vector.cpp:380:2:380:2 | call to operator* [post update] | | | vector.cpp:380:3:380:4 | i8 | vector.cpp:380:2:380:2 | call to operator* | TAINT | | vector.cpp:380:8:380:8 | 1 | vector.cpp:380:2:380:2 | call to operator* [post update] | TAINT | | vector.cpp:380:8:380:8 | 1 | vector.cpp:380:2:380:8 | ... = ... | | -| vector.cpp:381:7:381:8 | ref arg v8 | vector.cpp:382:1:382:1 | v8 | | +| vector.cpp:381:7:381:8 | ref arg v8 | vector.cpp:389:1:389:1 | v8 | | +| vector.cpp:383:34:383:35 | ref arg v9 | vector.cpp:388:7:388:8 | v9 | | +| vector.cpp:383:34:383:35 | ref arg v9 | vector.cpp:389:1:389:1 | v9 | | +| vector.cpp:383:34:383:35 | v9 | vector.cpp:383:37:383:41 | call to begin | TAINT | +| vector.cpp:383:37:383:41 | call to begin | vector.cpp:385:3:385:4 | i9 | | +| vector.cpp:383:37:383:41 | call to begin | vector.cpp:386:31:386:32 | i9 | | +| vector.cpp:385:2:385:2 | call to operator* [post update] | vector.cpp:388:7:388:8 | v9 | | +| vector.cpp:385:2:385:2 | call to operator* [post update] | vector.cpp:389:1:389:1 | v9 | | +| vector.cpp:385:2:385:15 | ... = ... | vector.cpp:385:2:385:2 | call to operator* [post update] | | +| vector.cpp:385:3:385:4 | i9 | vector.cpp:385:2:385:2 | call to operator* | TAINT | +| vector.cpp:385:8:385:13 | call to source | vector.cpp:385:2:385:2 | call to operator* [post update] | TAINT | +| vector.cpp:385:8:385:13 | call to source | vector.cpp:385:2:385:15 | ... = ... | | +| vector.cpp:386:31:386:32 | call to iterator [post update] | vector.cpp:388:7:388:8 | v9 | | +| vector.cpp:386:31:386:32 | call to iterator [post update] | vector.cpp:389:1:389:1 | v9 | | +| vector.cpp:386:31:386:32 | i9 | vector.cpp:386:31:386:32 | call to iterator | | +| vector.cpp:386:31:386:32 | i9 [post update] | vector.cpp:388:7:388:8 | v9 | | +| vector.cpp:386:31:386:32 | i9 [post update] | vector.cpp:389:1:389:1 | v9 | | +| vector.cpp:388:7:388:8 | ref arg v9 | vector.cpp:389:1:389:1 | v9 | | diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected index 889e1da17e69..01ef2e1a4947 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected @@ -337,3 +337,5 @@ | vector.cpp:375:7:375:8 | v7 | vector.cpp:369:9:369:14 | call to source | | vector.cpp:379:7:379:8 | v8 | vector.cpp:378:8:378:13 | call to source | | vector.cpp:381:7:381:8 | v8 | vector.cpp:378:8:378:13 | call to source | +| vector.cpp:388:7:388:8 | v9 | vector.cpp:330:10:330:15 | call to source | +| vector.cpp:388:7:388:8 | v9 | vector.cpp:385:8:385:13 | call to source | diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected index 0f6b7a574a53..173bb28f8314 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected @@ -286,3 +286,5 @@ | vector.cpp:375:7:375:8 | vector.cpp:369:9:369:14 | AST only | | vector.cpp:379:7:379:8 | vector.cpp:378:8:378:13 | AST only | | vector.cpp:381:7:381:8 | vector.cpp:378:8:378:13 | AST only | +| vector.cpp:388:7:388:8 | vector.cpp:330:10:330:15 | AST only | +| vector.cpp:388:7:388:8 | vector.cpp:385:8:385:13 | AST only | From 107e9770da5ebde3e06ba7fefd5952a0154ed105 Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Fri, 18 Sep 2020 14:12:33 -0700 Subject: [PATCH 12/25] C++: remove accidentally committed test code --- cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll | 5 ----- 1 file changed, 5 deletions(-) diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll index 45a537f80498..b9e5eadfcf56 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll @@ -253,11 +253,6 @@ private module PartialDefinitions { } } -predicate quickTest(PartialDefinition pd) { - pd instanceof DefinitionByReference and - pd instanceof IteratorPartialDefinition -} - import PartialDefinitions private import FlowVar_internal From b84bf5e9bb5a3a4562592a558290d476b68f83d3 Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Fri, 18 Sep 2020 14:18:38 -0700 Subject: [PATCH 13/25] C++: QLDoc for IteratorPartialDefinitionNode --- .../src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll index faa242aec64d..d71b3a4ad62c 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll @@ -304,6 +304,12 @@ private class VariablePartialDefinitionNode extends PartialDefinitionNode { override Node getPreUpdateNode() { pd.definesExpressions(_, result.asExpr()) } } +/** + * INTERNAL: do not use. + * + * A synthetic data flow node used for flow into a collection when an iterator + * write occurs in a callee. + */ class IteratorPartialDefinitionNode extends PartialDefinitionNode { override IteratorPartialDefinition pd; From bd7f5a41d1016b001fa1f8dbf3988fac6d93cfb1 Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Fri, 18 Sep 2020 14:19:29 -0700 Subject: [PATCH 14/25] C++: autoformat --- .../semmle/code/cpp/dataflow/internal/DataFlowUtil.qll | 8 +++----- cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll | 8 +++----- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll index d71b3a4ad62c..963f1a178261 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll @@ -284,12 +284,10 @@ abstract class PostUpdateNode extends Node { override Location getLocation() { result = getPreUpdateNode().getLocation() } } -private abstract class PartialDefinitionNode extends PostUpdateNode, TPartialDefinitionNode { +abstract private class PartialDefinitionNode extends PostUpdateNode, TPartialDefinitionNode { PartialDefinition pd; - PartialDefinitionNode() { - this = TPartialDefinitionNode(pd) - } + PartialDefinitionNode() { this = TPartialDefinitionNode(pd) } override Location getLocation() { result = pd.getActualLocation() } @@ -306,7 +304,7 @@ private class VariablePartialDefinitionNode extends PartialDefinitionNode { /** * INTERNAL: do not use. - * + * * A synthetic data flow node used for flow into a collection when an iterator * write occurs in a callee. */ diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll index b9e5eadfcf56..13f11f8b2750 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll @@ -112,13 +112,11 @@ private module PartialDefinitions { abstract class PartialDefinition extends Expr { ControlFlowNode node; - PartialDefinition() { - not this instanceof Conversion - } + PartialDefinition() { not this instanceof Conversion } - deprecated abstract predicate partiallyDefines(Variable v); + abstract deprecated predicate partiallyDefines(Variable v); - deprecated abstract predicate partiallyDefinesThis(ThisExpr e); + abstract deprecated predicate partiallyDefinesThis(ThisExpr e); /** * Gets the subBasicBlock where this `PartialDefinition` is defined. From 913881b17b869602b45e37d5044949e1ba72bde8 Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Mon, 21 Sep 2020 16:10:37 -0700 Subject: [PATCH 15/25] C++: Add test for iterator false positive --- .../dataflow/taint-tests/localTaint.expected | 476 ++++++++++-------- .../dataflow/taint-tests/taint.expected | 28 +- .../dataflow/taint-tests/test_diff.expected | 28 +- .../dataflow/taint-tests/vector.cpp | 14 +- 4 files changed, 298 insertions(+), 248 deletions(-) diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected index ae2bc9b563e0..365216bce3c1 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected @@ -3701,224 +3701,258 @@ | vector.cpp:330:3:330:6 | iter | vector.cpp:330:2:330:2 | call to operator* | TAINT | | vector.cpp:330:10:330:15 | call to source | vector.cpp:330:2:330:2 | call to operator* [post update] | TAINT | | vector.cpp:330:10:330:15 | call to source | vector.cpp:330:2:330:17 | ... = ... | | -| vector.cpp:333:38:333:38 | b | vector.cpp:368:5:368:5 | b | | -| vector.cpp:334:22:334:24 | call to vector | vector.cpp:336:34:336:35 | v1 | | -| vector.cpp:334:22:334:24 | call to vector | vector.cpp:338:7:338:8 | v1 | | -| vector.cpp:334:22:334:24 | call to vector | vector.cpp:389:1:389:1 | v1 | | -| vector.cpp:334:30:334:32 | call to vector | vector.cpp:340:38:340:39 | v2 | | -| vector.cpp:334:30:334:32 | call to vector | vector.cpp:340:56:340:57 | v2 | | -| vector.cpp:334:30:334:32 | call to vector | vector.cpp:343:7:343:8 | v2 | | -| vector.cpp:334:30:334:32 | call to vector | vector.cpp:389:1:389:1 | v2 | | -| vector.cpp:334:38:334:40 | call to vector | vector.cpp:345:15:345:16 | v3 | | -| vector.cpp:334:38:334:40 | call to vector | vector.cpp:348:7:348:8 | v3 | | -| vector.cpp:334:38:334:40 | call to vector | vector.cpp:389:1:389:1 | v3 | | -| vector.cpp:334:46:334:48 | call to vector | vector.cpp:350:38:350:39 | v4 | | -| vector.cpp:334:46:334:48 | call to vector | vector.cpp:350:56:350:57 | v4 | | -| vector.cpp:334:46:334:48 | call to vector | vector.cpp:353:7:353:8 | v4 | | -| vector.cpp:334:46:334:48 | call to vector | vector.cpp:389:1:389:1 | v4 | | -| vector.cpp:334:54:334:56 | call to vector | vector.cpp:355:34:355:35 | v5 | | -| vector.cpp:334:54:334:56 | call to vector | vector.cpp:357:7:357:8 | v5 | | -| vector.cpp:334:54:334:56 | call to vector | vector.cpp:359:7:359:8 | v5 | | -| vector.cpp:334:54:334:56 | call to vector | vector.cpp:389:1:389:1 | v5 | | -| vector.cpp:334:62:334:64 | call to vector | vector.cpp:361:34:361:35 | v6 | | -| vector.cpp:334:62:334:64 | call to vector | vector.cpp:363:7:363:8 | v6 | | -| vector.cpp:334:62:334:64 | call to vector | vector.cpp:364:2:364:3 | v6 | | -| vector.cpp:334:62:334:64 | call to vector | vector.cpp:365:7:365:8 | v6 | | -| vector.cpp:334:62:334:64 | call to vector | vector.cpp:389:1:389:1 | v6 | | -| vector.cpp:334:70:334:72 | call to vector | vector.cpp:367:34:367:35 | v7 | | -| vector.cpp:334:70:334:72 | call to vector | vector.cpp:370:8:370:9 | v7 | | -| vector.cpp:334:70:334:72 | call to vector | vector.cpp:373:8:373:9 | v7 | | -| vector.cpp:334:70:334:72 | call to vector | vector.cpp:375:7:375:8 | v7 | | -| vector.cpp:334:70:334:72 | call to vector | vector.cpp:389:1:389:1 | v7 | | -| vector.cpp:334:78:334:80 | call to vector | vector.cpp:377:34:377:35 | v8 | | -| vector.cpp:334:78:334:80 | call to vector | vector.cpp:379:7:379:8 | v8 | | -| vector.cpp:334:78:334:80 | call to vector | vector.cpp:381:7:381:8 | v8 | | -| vector.cpp:334:78:334:80 | call to vector | vector.cpp:389:1:389:1 | v8 | | -| vector.cpp:334:86:334:88 | call to vector | vector.cpp:383:34:383:35 | v9 | | -| vector.cpp:334:86:334:88 | call to vector | vector.cpp:388:7:388:8 | v9 | | -| vector.cpp:334:86:334:88 | call to vector | vector.cpp:389:1:389:1 | v9 | | -| vector.cpp:336:34:336:35 | ref arg v1 | vector.cpp:338:7:338:8 | v1 | | -| vector.cpp:336:34:336:35 | ref arg v1 | vector.cpp:389:1:389:1 | v1 | | -| vector.cpp:336:34:336:35 | v1 | vector.cpp:336:37:336:41 | call to begin | TAINT | -| vector.cpp:336:37:336:41 | call to begin | vector.cpp:337:3:337:4 | i1 | | -| vector.cpp:337:2:337:2 | call to operator* [post update] | vector.cpp:338:7:338:8 | v1 | | -| vector.cpp:337:2:337:2 | call to operator* [post update] | vector.cpp:389:1:389:1 | v1 | | -| 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:337:2:337:2 | call to operator* [post update] | TAINT | -| vector.cpp:337:8:337:13 | call to source | vector.cpp:337:2:337:15 | ... = ... | | -| vector.cpp:338:7:338:8 | ref arg v1 | vector.cpp:389:1:389: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 | | -| vector.cpp:340:38:340:39 | ref arg v2 | vector.cpp:389:1:389:1 | v2 | | -| vector.cpp:340:38:340:39 | v2 | vector.cpp:340:41:340:45 | call to begin | TAINT | -| vector.cpp:340:41:340:45 | call to begin | vector.cpp:340:50:340:51 | it | | -| vector.cpp:340:41:340:45 | call to begin | vector.cpp:340:68:340:69 | it | | -| vector.cpp:340:41:340:45 | call to begin | vector.cpp:341:4:341:5 | it | | -| vector.cpp:340:56:340:57 | ref arg v2 | vector.cpp:340:56:340:57 | v2 | | -| vector.cpp:340:56:340:57 | ref arg v2 | vector.cpp:343:7:343:8 | v2 | | -| vector.cpp:340:56:340:57 | ref arg v2 | vector.cpp:389:1:389:1 | v2 | | -| vector.cpp:340:56:340:57 | v2 | vector.cpp:340:59:340:61 | call to end | TAINT | -| vector.cpp:340:68:340:69 | it | vector.cpp:340:66:340:66 | call to operator++ | | -| vector.cpp:340:68:340:69 | ref arg it | vector.cpp:340:50:340:51 | it | | -| vector.cpp:340:68:340:69 | ref arg it | vector.cpp:340:68:340:69 | it | | -| vector.cpp:340:68:340:69 | ref arg it | vector.cpp:341:4:341:5 | it | | -| vector.cpp:341:3:341:3 | call to operator* [post update] | vector.cpp:340:56:340:57 | v2 | | -| vector.cpp:341:3:341:3 | call to operator* [post update] | vector.cpp:343:7:343:8 | v2 | | -| vector.cpp:341:3:341:3 | call to operator* [post update] | vector.cpp:389:1:389:1 | v2 | | -| 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:341:3:341:3 | call to operator* [post update] | TAINT | -| vector.cpp:341:9:341:14 | call to source | vector.cpp:341:3:341:16 | ... = ... | | -| vector.cpp:343:7:343:8 | ref arg v2 | vector.cpp:389:1:389: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++ | | -| vector.cpp:345:15:345:15 | (__end) | vector.cpp:345:15:345:15 | call to iterator | | -| vector.cpp:345:15:345:15 | (__range) | vector.cpp:345:15:345:15 | call to begin | TAINT | -| vector.cpp:345:15:345:15 | (__range) | vector.cpp:345:15:345:15 | call to end | TAINT | -| vector.cpp:345:15:345:15 | call to begin | vector.cpp:345:15:345:15 | (__begin) | | -| vector.cpp:345:15:345:15 | call to begin | vector.cpp:345:15:345:15 | (__begin) | | -| vector.cpp:345:15:345:15 | call to begin | vector.cpp:345:15:345:15 | (__begin) | | -| vector.cpp:345:15:345:15 | call to end | vector.cpp:345:15:345:15 | (__end) | | -| vector.cpp:345:15:345:15 | ref arg (__begin) | vector.cpp:345:15:345:15 | (__begin) | | -| vector.cpp:345:15:345:15 | ref arg (__begin) | vector.cpp:345:15:345:15 | (__begin) | | -| vector.cpp:345:15:345:15 | ref arg (__begin) | vector.cpp:345:15:345:15 | (__begin) | | -| vector.cpp:345:15:345:15 | ref arg (__range) | vector.cpp:345:15:345:15 | (__range) | | -| vector.cpp:345:15:345:16 | v3 | vector.cpp:345:15:345:15 | (__range) | | -| vector.cpp:345:15:345:16 | v3 | vector.cpp:345:15:345:15 | (__range) | | -| vector.cpp:345:15:345:16 | v3 | vector.cpp:345:15:345:15 | call to operator* | TAINT | -| vector.cpp:346:3:346:14 | ... = ... | vector.cpp:346:3:346:3 | x [post update] | | -| vector.cpp:346:7:346:12 | call to source | vector.cpp:346:3:346:14 | ... = ... | | -| vector.cpp:348:7:348:8 | ref arg v3 | vector.cpp:389:1:389:1 | v3 | | -| vector.cpp:350:38:350:39 | ref arg v4 | vector.cpp:350:56:350:57 | v4 | | -| vector.cpp:350:38:350:39 | ref arg v4 | vector.cpp:353:7:353:8 | v4 | | -| vector.cpp:350:38:350:39 | ref arg v4 | vector.cpp:389:1:389:1 | v4 | | -| vector.cpp:350:38:350:39 | v4 | vector.cpp:350:41:350:45 | call to begin | TAINT | -| vector.cpp:350:41:350:45 | call to begin | vector.cpp:350:50:350:51 | it | | -| vector.cpp:350:41:350:45 | call to begin | vector.cpp:350:68:350:69 | it | | -| vector.cpp:350:41:350:45 | call to begin | vector.cpp:351:32:351:33 | it | | -| vector.cpp:350:56:350:57 | ref arg v4 | vector.cpp:350:56:350:57 | v4 | | -| vector.cpp:350:56:350:57 | ref arg v4 | vector.cpp:353:7:353:8 | v4 | | -| vector.cpp:350:56:350:57 | ref arg v4 | vector.cpp:389:1:389:1 | v4 | | -| vector.cpp:350:56:350:57 | v4 | vector.cpp:350:59:350:61 | call to end | TAINT | -| vector.cpp:350:68:350:69 | it | vector.cpp:350:66:350:66 | call to operator++ | | -| vector.cpp:350:68:350:69 | ref arg it | vector.cpp:350:50:350:51 | it | | -| vector.cpp:350:68:350:69 | ref arg it | vector.cpp:350:68:350:69 | it | | -| vector.cpp:350:68:350:69 | ref arg it | vector.cpp:351:32:351:33 | it | | -| vector.cpp:351:32:351:33 | call to iterator [post update] | vector.cpp:350:56:350:57 | v4 | | -| vector.cpp:351:32:351:33 | call to iterator [post update] | vector.cpp:353:7:353:8 | v4 | | -| vector.cpp:351:32:351:33 | call to iterator [post update] | vector.cpp:389:1:389:1 | v4 | | -| vector.cpp:351:32:351:33 | it | vector.cpp:351:32:351:33 | call to iterator | | -| vector.cpp:351:32:351:33 | it [post update] | vector.cpp:350:56:350:57 | v4 | | -| vector.cpp:351:32:351:33 | it [post update] | vector.cpp:353:7:353:8 | v4 | | -| vector.cpp:351:32:351:33 | it [post update] | vector.cpp:389:1:389:1 | v4 | | -| vector.cpp:353:7:353:8 | ref arg v4 | vector.cpp:389:1:389:1 | v4 | | -| vector.cpp:355:34:355:35 | ref arg v5 | vector.cpp:357:7:357:8 | v5 | | -| vector.cpp:355:34:355:35 | ref arg v5 | vector.cpp:359:7:359:8 | v5 | | -| vector.cpp:355:34:355:35 | ref arg v5 | vector.cpp:389:1:389:1 | v5 | | -| vector.cpp:355:34:355:35 | v5 | vector.cpp:355:37:355:41 | call to begin | TAINT | -| vector.cpp:355:37:355:41 | call to begin | vector.cpp:356:3:356:4 | i5 | | -| vector.cpp:355:37:355:41 | call to begin | vector.cpp:358:3:358:4 | i5 | | -| vector.cpp:356:2:356:2 | call to operator* [post update] | vector.cpp:357:7:357:8 | v5 | | -| vector.cpp:356:2:356:2 | call to operator* [post update] | vector.cpp:359:7:359:8 | v5 | | -| vector.cpp:356:2:356:2 | call to operator* [post update] | vector.cpp:389:1:389:1 | v5 | | -| vector.cpp:356:2:356:15 | ... = ... | vector.cpp:356:2:356:2 | call to operator* [post update] | | -| vector.cpp:356:3:356:4 | i5 | vector.cpp:356:2:356:2 | call to operator* | TAINT | -| vector.cpp:356:8:356:13 | call to source | vector.cpp:356:2:356:2 | call to operator* [post update] | TAINT | -| vector.cpp:356:8:356:13 | call to source | vector.cpp:356:2:356:15 | ... = ... | | -| vector.cpp:357:7:357:8 | ref arg v5 | vector.cpp:359:7:359:8 | v5 | | -| vector.cpp:357:7:357:8 | ref arg v5 | vector.cpp:389:1:389:1 | v5 | | -| vector.cpp:358:2:358:2 | call to operator* [post update] | vector.cpp:359:7:359:8 | v5 | | -| vector.cpp:358:2:358:2 | call to operator* [post update] | vector.cpp:389:1:389:1 | v5 | | -| vector.cpp:358:2:358:8 | ... = ... | vector.cpp:358:2:358:2 | call to operator* [post update] | | -| vector.cpp:358:3:358:4 | i5 | vector.cpp:358:2:358:2 | call to operator* | TAINT | -| vector.cpp:358:8:358:8 | 1 | vector.cpp:358:2:358:2 | call to operator* [post update] | TAINT | -| vector.cpp:358:8:358:8 | 1 | vector.cpp:358:2:358:8 | ... = ... | | -| vector.cpp:359:7:359:8 | ref arg v5 | vector.cpp:389:1:389:1 | v5 | | -| vector.cpp:361:34:361:35 | ref arg v6 | vector.cpp:363:7:363:8 | v6 | | -| vector.cpp:361:34:361:35 | ref arg v6 | vector.cpp:364:2:364:3 | v6 | | -| vector.cpp:361:34:361:35 | ref arg v6 | vector.cpp:365:7:365:8 | v6 | | -| vector.cpp:361:34:361:35 | ref arg v6 | vector.cpp:389:1:389:1 | v6 | | -| vector.cpp:361:34:361:35 | v6 | vector.cpp:361:37:361:41 | call to begin | TAINT | -| vector.cpp:361:37:361:41 | call to begin | vector.cpp:362:3:362:4 | i6 | | -| vector.cpp:362:2:362:2 | call to operator* [post update] | vector.cpp:363:7:363:8 | v6 | | -| vector.cpp:362:2:362:2 | call to operator* [post update] | vector.cpp:364:2:364:3 | v6 | | -| vector.cpp:362:2:362:2 | call to operator* [post update] | vector.cpp:365:7:365:8 | v6 | | -| vector.cpp:362:2:362:2 | call to operator* [post update] | vector.cpp:389:1:389:1 | v6 | | -| vector.cpp:362:2:362:15 | ... = ... | vector.cpp:362:2:362:2 | call to operator* [post update] | | -| vector.cpp:362:3:362:4 | i6 | vector.cpp:362:2:362:2 | call to operator* | TAINT | -| vector.cpp:362:8:362:13 | call to source | vector.cpp:362:2:362:2 | call to operator* [post update] | TAINT | -| vector.cpp:362:8:362:13 | call to source | vector.cpp:362:2:362:15 | ... = ... | | -| vector.cpp:363:7:363:8 | ref arg v6 | vector.cpp:364:2:364:3 | v6 | | -| vector.cpp:363:7:363:8 | ref arg v6 | vector.cpp:365:7:365:8 | v6 | | -| vector.cpp:363:7:363:8 | ref arg v6 | vector.cpp:389:1:389:1 | v6 | | -| vector.cpp:364:2:364:3 | ref arg v6 | vector.cpp:365:7:365:8 | v6 | | -| vector.cpp:364:2:364:3 | ref arg v6 | vector.cpp:389:1:389:1 | v6 | | -| vector.cpp:364:7:364:26 | call to vector | vector.cpp:364:2:364:3 | ref arg v6 | TAINT | -| vector.cpp:364:7:364:26 | call to vector | vector.cpp:364:5:364:5 | call to operator= | TAINT | -| vector.cpp:365:7:365:8 | ref arg v6 | vector.cpp:389:1:389:1 | v6 | | -| vector.cpp:367:34:367:35 | ref arg v7 | vector.cpp:370:8:370:9 | v7 | | -| vector.cpp:367:34:367:35 | ref arg v7 | vector.cpp:373:8:373:9 | v7 | | -| vector.cpp:367:34:367:35 | ref arg v7 | vector.cpp:375:7:375:8 | v7 | | -| vector.cpp:367:34:367:35 | ref arg v7 | vector.cpp:389:1:389:1 | v7 | | -| vector.cpp:367:34:367:35 | v7 | vector.cpp:367:37:367:41 | call to begin | TAINT | -| vector.cpp:367:37:367:41 | call to begin | vector.cpp:369:4:369:5 | i7 | | -| vector.cpp:367:37:367:41 | call to begin | vector.cpp:372:4:372:5 | i7 | | -| vector.cpp:369:3:369:3 | call to operator* [post update] | vector.cpp:370:8:370:9 | v7 | | -| vector.cpp:369:3:369:3 | call to operator* [post update] | vector.cpp:375:7:375:8 | v7 | | -| vector.cpp:369:3:369:3 | call to operator* [post update] | vector.cpp:389:1:389:1 | v7 | | -| vector.cpp:369:3:369:16 | ... = ... | vector.cpp:369:3:369:3 | call to operator* [post update] | | -| vector.cpp:369:4:369:5 | i7 | vector.cpp:369:3:369:3 | call to operator* | TAINT | -| vector.cpp:369:9:369:14 | call to source | vector.cpp:369:3:369:3 | call to operator* [post update] | TAINT | -| vector.cpp:369:9:369:14 | call to source | vector.cpp:369:3:369:16 | ... = ... | | -| vector.cpp:370:8:370:9 | ref arg v7 | vector.cpp:375:7:375:8 | v7 | | -| vector.cpp:370:8:370:9 | ref arg v7 | vector.cpp:389:1:389:1 | v7 | | -| vector.cpp:372:3:372:3 | call to operator* [post update] | vector.cpp:373:8:373:9 | v7 | | -| vector.cpp:372:3:372:3 | call to operator* [post update] | vector.cpp:375:7:375:8 | v7 | | -| vector.cpp:372:3:372:3 | call to operator* [post update] | vector.cpp:389:1:389:1 | v7 | | -| vector.cpp:372:3:372:9 | ... = ... | vector.cpp:372:3:372:3 | call to operator* [post update] | | -| vector.cpp:372:4:372:5 | i7 | vector.cpp:372:3:372:3 | call to operator* | TAINT | -| vector.cpp:372:9:372:9 | 1 | vector.cpp:372:3:372:3 | call to operator* [post update] | TAINT | -| vector.cpp:372:9:372:9 | 1 | vector.cpp:372:3:372:9 | ... = ... | | -| vector.cpp:373:8:373:9 | ref arg v7 | vector.cpp:375:7:375:8 | v7 | | -| vector.cpp:373:8:373:9 | ref arg v7 | vector.cpp:389:1:389:1 | v7 | | -| vector.cpp:375:7:375:8 | ref arg v7 | vector.cpp:389:1:389:1 | v7 | | -| vector.cpp:377:34:377:35 | ref arg v8 | vector.cpp:379:7:379:8 | v8 | | -| vector.cpp:377:34:377:35 | ref arg v8 | vector.cpp:381:7:381:8 | v8 | | -| vector.cpp:377:34:377:35 | ref arg v8 | vector.cpp:389:1:389:1 | v8 | | -| vector.cpp:377:34:377:35 | v8 | vector.cpp:377:37:377:41 | call to begin | TAINT | -| vector.cpp:377:37:377:41 | call to begin | vector.cpp:378:3:378:4 | i8 | | -| vector.cpp:377:37:377:41 | call to begin | vector.cpp:380:3:380:4 | i8 | | -| vector.cpp:378:2:378:2 | call to operator* [post update] | vector.cpp:379:7:379:8 | v8 | | -| vector.cpp:378:2:378:2 | call to operator* [post update] | vector.cpp:381:7:381:8 | v8 | | -| vector.cpp:378:2:378:2 | call to operator* [post update] | vector.cpp:389:1:389:1 | v8 | | -| vector.cpp:378:2:378:15 | ... = ... | vector.cpp:378:2:378:2 | call to operator* [post update] | | -| vector.cpp:378:3:378:4 | i8 | vector.cpp:378:2:378:2 | call to operator* | TAINT | -| vector.cpp:378:8:378:13 | call to source | vector.cpp:378:2:378:2 | call to operator* [post update] | TAINT | -| vector.cpp:378:8:378:13 | call to source | vector.cpp:378:2:378:15 | ... = ... | | -| vector.cpp:379:7:379:8 | ref arg v8 | vector.cpp:381:7:381:8 | v8 | | -| vector.cpp:379:7:379:8 | ref arg v8 | vector.cpp:389:1:389:1 | v8 | | -| vector.cpp:380:2:380:2 | call to operator* [post update] | vector.cpp:381:7:381:8 | v8 | | -| vector.cpp:380:2:380:2 | call to operator* [post update] | vector.cpp:389:1:389:1 | v8 | | -| vector.cpp:380:2:380:8 | ... = ... | vector.cpp:380:2:380:2 | call to operator* [post update] | | -| vector.cpp:380:3:380:4 | i8 | vector.cpp:380:2:380:2 | call to operator* | TAINT | -| vector.cpp:380:8:380:8 | 1 | vector.cpp:380:2:380:2 | call to operator* [post update] | TAINT | -| vector.cpp:380:8:380:8 | 1 | vector.cpp:380:2:380:8 | ... = ... | | -| vector.cpp:381:7:381:8 | ref arg v8 | vector.cpp:389:1:389:1 | v8 | | -| vector.cpp:383:34:383:35 | ref arg v9 | vector.cpp:388:7:388:8 | v9 | | -| vector.cpp:383:34:383:35 | ref arg v9 | vector.cpp:389:1:389:1 | v9 | | -| vector.cpp:383:34:383:35 | v9 | vector.cpp:383:37:383:41 | call to begin | TAINT | -| vector.cpp:383:37:383:41 | call to begin | vector.cpp:385:3:385:4 | i9 | | -| vector.cpp:383:37:383:41 | call to begin | vector.cpp:386:31:386:32 | i9 | | -| vector.cpp:385:2:385:2 | call to operator* [post update] | vector.cpp:388:7:388:8 | v9 | | -| vector.cpp:385:2:385:2 | call to operator* [post update] | vector.cpp:389:1:389:1 | v9 | | -| vector.cpp:385:2:385:15 | ... = ... | vector.cpp:385:2:385:2 | call to operator* [post update] | | -| vector.cpp:385:3:385:4 | i9 | vector.cpp:385:2:385:2 | call to operator* | TAINT | -| vector.cpp:385:8:385:13 | call to source | vector.cpp:385:2:385:2 | call to operator* [post update] | TAINT | -| vector.cpp:385:8:385:13 | call to source | vector.cpp:385:2:385:15 | ... = ... | | -| vector.cpp:386:31:386:32 | call to iterator [post update] | vector.cpp:388:7:388:8 | v9 | | -| vector.cpp:386:31:386:32 | call to iterator [post update] | vector.cpp:389:1:389:1 | v9 | | -| vector.cpp:386:31:386:32 | i9 | vector.cpp:386:31:386:32 | call to iterator | | -| vector.cpp:386:31:386:32 | i9 [post update] | vector.cpp:388:7:388:8 | v9 | | -| vector.cpp:386:31:386:32 | i9 [post update] | vector.cpp:389:1:389:1 | v9 | | -| vector.cpp:388:7:388:8 | ref arg v9 | vector.cpp:389:1:389:1 | v9 | | +| vector.cpp:333:64:333:67 | iter | vector.cpp:333:64:333:67 | iter | | +| vector.cpp:333:64:333:67 | iter | vector.cpp:334:3:334:6 | iter | | +| vector.cpp:333:74:333:74 | i | vector.cpp:334:10:334:10 | i | | +| vector.cpp:334:2:334:2 | call to operator* [post update] | vector.cpp:333:64:333:67 | iter | | +| vector.cpp:334:2:334:10 | ... = ... | vector.cpp:334:2:334:2 | call to operator* [post update] | | +| vector.cpp:334:3:334:6 | iter | vector.cpp:334:2:334:2 | call to operator* | TAINT | +| vector.cpp:334:10:334:10 | i | vector.cpp:334:2:334:2 | call to operator* [post update] | TAINT | +| vector.cpp:334:10:334:10 | i | vector.cpp:334:2:334:10 | ... = ... | | +| vector.cpp:337:38:337:38 | b | vector.cpp:372:5:372:5 | b | | +| vector.cpp:338:22:338:24 | call to vector | vector.cpp:340:34:340:35 | v1 | | +| vector.cpp:338:22:338:24 | call to vector | vector.cpp:342:7:342:8 | v1 | | +| vector.cpp:338:22:338:24 | call to vector | vector.cpp:401:1:401:1 | v1 | | +| vector.cpp:338:30:338:32 | call to vector | vector.cpp:344:38:344:39 | v2 | | +| vector.cpp:338:30:338:32 | call to vector | vector.cpp:344:56:344:57 | v2 | | +| vector.cpp:338:30:338:32 | call to vector | vector.cpp:347:7:347:8 | v2 | | +| vector.cpp:338:30:338:32 | call to vector | vector.cpp:401:1:401:1 | v2 | | +| vector.cpp:338:38:338:40 | call to vector | vector.cpp:349:15:349:16 | v3 | | +| vector.cpp:338:38:338:40 | call to vector | vector.cpp:352:7:352:8 | v3 | | +| vector.cpp:338:38:338:40 | call to vector | vector.cpp:401:1:401:1 | v3 | | +| vector.cpp:338:46:338:48 | call to vector | vector.cpp:354:38:354:39 | v4 | | +| vector.cpp:338:46:338:48 | call to vector | vector.cpp:354:56:354:57 | v4 | | +| vector.cpp:338:46:338:48 | call to vector | vector.cpp:357:7:357:8 | v4 | | +| vector.cpp:338:46:338:48 | call to vector | vector.cpp:401:1:401:1 | v4 | | +| vector.cpp:338:54:338:56 | call to vector | vector.cpp:359:34:359:35 | v5 | | +| vector.cpp:338:54:338:56 | call to vector | vector.cpp:361:7:361:8 | v5 | | +| vector.cpp:338:54:338:56 | call to vector | vector.cpp:363:7:363:8 | v5 | | +| vector.cpp:338:54:338:56 | call to vector | vector.cpp:401:1:401:1 | v5 | | +| vector.cpp:338:62:338:64 | call to vector | vector.cpp:365:34:365:35 | v6 | | +| vector.cpp:338:62:338:64 | call to vector | vector.cpp:367:7:367:8 | v6 | | +| vector.cpp:338:62:338:64 | call to vector | vector.cpp:368:2:368:3 | v6 | | +| vector.cpp:338:62:338:64 | call to vector | vector.cpp:369:7:369:8 | v6 | | +| vector.cpp:338:62:338:64 | call to vector | vector.cpp:401:1:401:1 | v6 | | +| vector.cpp:338:70:338:72 | call to vector | vector.cpp:371:34:371:35 | v7 | | +| vector.cpp:338:70:338:72 | call to vector | vector.cpp:374:8:374:9 | v7 | | +| vector.cpp:338:70:338:72 | call to vector | vector.cpp:377:8:377:9 | v7 | | +| vector.cpp:338:70:338:72 | call to vector | vector.cpp:379:7:379:8 | v7 | | +| vector.cpp:338:70:338:72 | call to vector | vector.cpp:401:1:401:1 | v7 | | +| vector.cpp:338:78:338:80 | call to vector | vector.cpp:381:34:381:35 | v8 | | +| vector.cpp:338:78:338:80 | call to vector | vector.cpp:383:7:383:8 | v8 | | +| vector.cpp:338:78:338:80 | call to vector | vector.cpp:385:7:385:8 | v8 | | +| vector.cpp:338:78:338:80 | call to vector | vector.cpp:401:1:401:1 | v8 | | +| vector.cpp:338:86:338:88 | call to vector | vector.cpp:387:34:387:35 | v9 | | +| vector.cpp:338:86:338:88 | call to vector | vector.cpp:392:7:392:8 | v9 | | +| vector.cpp:338:86:338:88 | call to vector | vector.cpp:401:1:401:1 | v9 | | +| vector.cpp:338:95:338:97 | call to vector | vector.cpp:394:35:394:37 | v10 | | +| vector.cpp:338:95:338:97 | call to vector | vector.cpp:396:7:396:9 | v10 | | +| vector.cpp:338:95:338:97 | call to vector | vector.cpp:401:1:401:1 | v10 | | +| vector.cpp:338:104:338:106 | call to vector | vector.cpp:398:35:398:37 | v11 | | +| vector.cpp:338:104:338:106 | call to vector | vector.cpp:400:7:400:9 | v11 | | +| vector.cpp:338:104:338:106 | call to vector | vector.cpp:401:1:401:1 | v11 | | +| vector.cpp:340:34:340:35 | ref arg v1 | vector.cpp:342:7:342:8 | v1 | | +| vector.cpp:340:34:340:35 | ref arg v1 | vector.cpp:401:1:401:1 | v1 | | +| vector.cpp:340:34:340:35 | v1 | vector.cpp:340:37:340:41 | call to begin | TAINT | +| vector.cpp:340:37:340:41 | call to begin | vector.cpp:341:3:341:4 | i1 | | +| vector.cpp:341:2:341:2 | call to operator* [post update] | vector.cpp:342:7:342:8 | v1 | | +| vector.cpp:341:2:341:2 | call to operator* [post update] | vector.cpp:401:1:401:1 | v1 | | +| vector.cpp:341:2:341:15 | ... = ... | vector.cpp:341:2:341:2 | call to operator* [post update] | | +| vector.cpp:341:3:341:4 | i1 | vector.cpp:341:2:341:2 | call to operator* | TAINT | +| vector.cpp:341:8:341:13 | call to source | vector.cpp:341:2:341:2 | call to operator* [post update] | TAINT | +| vector.cpp:341:8:341:13 | call to source | vector.cpp:341:2:341:15 | ... = ... | | +| vector.cpp:342:7:342:8 | ref arg v1 | vector.cpp:401:1:401:1 | v1 | | +| vector.cpp:344:38:344:39 | ref arg v2 | vector.cpp:344:56:344:57 | v2 | | +| vector.cpp:344:38:344:39 | ref arg v2 | vector.cpp:347:7:347:8 | v2 | | +| vector.cpp:344:38:344:39 | ref arg v2 | vector.cpp:401:1:401:1 | v2 | | +| vector.cpp:344:38:344:39 | v2 | vector.cpp:344:41:344:45 | call to begin | TAINT | +| vector.cpp:344:41:344:45 | call to begin | vector.cpp:344:50:344:51 | it | | +| vector.cpp:344:41:344:45 | call to begin | vector.cpp:344:68:344:69 | it | | +| vector.cpp:344:41:344:45 | call to begin | vector.cpp:345:4:345:5 | it | | +| vector.cpp:344:56:344:57 | ref arg v2 | vector.cpp:344:56:344:57 | v2 | | +| vector.cpp:344:56:344:57 | ref arg v2 | vector.cpp:347:7:347:8 | v2 | | +| vector.cpp:344:56:344:57 | ref arg v2 | vector.cpp:401:1:401:1 | v2 | | +| vector.cpp:344:56:344:57 | v2 | vector.cpp:344:59:344:61 | call to end | TAINT | +| vector.cpp:344:68:344:69 | it | vector.cpp:344:66:344:66 | call to operator++ | | +| vector.cpp:344:68:344:69 | ref arg it | vector.cpp:344:50:344:51 | it | | +| vector.cpp:344:68:344:69 | ref arg it | vector.cpp:344:68:344:69 | it | | +| vector.cpp:344:68:344:69 | ref arg it | vector.cpp:345:4:345:5 | it | | +| vector.cpp:345:3:345:3 | call to operator* [post update] | vector.cpp:344:56:344:57 | v2 | | +| vector.cpp:345:3:345:3 | call to operator* [post update] | vector.cpp:347:7:347:8 | v2 | | +| vector.cpp:345:3:345:3 | call to operator* [post update] | vector.cpp:401:1:401:1 | v2 | | +| vector.cpp:345:3:345:16 | ... = ... | vector.cpp:345:3:345:3 | call to operator* [post update] | | +| vector.cpp:345:4:345:5 | it | vector.cpp:345:3:345:3 | call to operator* | TAINT | +| vector.cpp:345:9:345:14 | call to source | vector.cpp:345:3:345:3 | call to operator* [post update] | TAINT | +| vector.cpp:345:9:345:14 | call to source | vector.cpp:345:3:345:16 | ... = ... | | +| vector.cpp:347:7:347:8 | ref arg v2 | vector.cpp:401:1:401:1 | v2 | | +| vector.cpp:349:15:349:15 | (__begin) | vector.cpp:349:15:349:15 | call to operator* | TAINT | +| vector.cpp:349:15:349:15 | (__begin) | vector.cpp:349:15:349:15 | call to operator++ | | +| vector.cpp:349:15:349:15 | (__end) | vector.cpp:349:15:349:15 | call to iterator | | +| vector.cpp:349:15:349:15 | (__range) | vector.cpp:349:15:349:15 | call to begin | TAINT | +| vector.cpp:349:15:349:15 | (__range) | vector.cpp:349:15:349:15 | call to end | TAINT | +| vector.cpp:349:15:349:15 | call to begin | vector.cpp:349:15:349:15 | (__begin) | | +| vector.cpp:349:15:349:15 | call to begin | vector.cpp:349:15:349:15 | (__begin) | | +| vector.cpp:349:15:349:15 | call to begin | vector.cpp:349:15:349:15 | (__begin) | | +| vector.cpp:349:15:349:15 | call to end | vector.cpp:349:15:349:15 | (__end) | | +| vector.cpp:349:15:349:15 | ref arg (__begin) | vector.cpp:349:15:349:15 | (__begin) | | +| vector.cpp:349:15:349:15 | ref arg (__begin) | vector.cpp:349:15:349:15 | (__begin) | | +| vector.cpp:349:15:349:15 | ref arg (__begin) | vector.cpp:349:15:349:15 | (__begin) | | +| vector.cpp:349:15:349:15 | ref arg (__range) | vector.cpp:349:15:349:15 | (__range) | | +| vector.cpp:349:15:349:16 | v3 | vector.cpp:349:15:349:15 | (__range) | | +| vector.cpp:349:15:349:16 | v3 | vector.cpp:349:15:349:15 | (__range) | | +| vector.cpp:349:15:349:16 | v3 | vector.cpp:349:15:349:15 | call to operator* | TAINT | +| vector.cpp:350:3:350:14 | ... = ... | vector.cpp:350:3:350:3 | x [post update] | | +| vector.cpp:350:7:350:12 | call to source | vector.cpp:350:3:350:14 | ... = ... | | +| vector.cpp:352:7:352:8 | ref arg v3 | vector.cpp:401:1:401:1 | v3 | | +| vector.cpp:354:38:354:39 | ref arg v4 | vector.cpp:354:56:354:57 | v4 | | +| vector.cpp:354:38:354:39 | ref arg v4 | vector.cpp:357:7:357:8 | v4 | | +| vector.cpp:354:38:354:39 | ref arg v4 | vector.cpp:401:1:401:1 | v4 | | +| vector.cpp:354:38:354:39 | v4 | vector.cpp:354:41:354:45 | call to begin | TAINT | +| vector.cpp:354:41:354:45 | call to begin | vector.cpp:354:50:354:51 | it | | +| vector.cpp:354:41:354:45 | call to begin | vector.cpp:354:68:354:69 | it | | +| vector.cpp:354:41:354:45 | call to begin | vector.cpp:355:32:355:33 | it | | +| vector.cpp:354:56:354:57 | ref arg v4 | vector.cpp:354:56:354:57 | v4 | | +| vector.cpp:354:56:354:57 | ref arg v4 | vector.cpp:357:7:357:8 | v4 | | +| vector.cpp:354:56:354:57 | ref arg v4 | vector.cpp:401:1:401:1 | v4 | | +| vector.cpp:354:56:354:57 | v4 | vector.cpp:354:59:354:61 | call to end | TAINT | +| vector.cpp:354:68:354:69 | it | vector.cpp:354:66:354:66 | call to operator++ | | +| vector.cpp:354:68:354:69 | ref arg it | vector.cpp:354:50:354:51 | it | | +| vector.cpp:354:68:354:69 | ref arg it | vector.cpp:354:68:354:69 | it | | +| vector.cpp:354:68:354:69 | ref arg it | vector.cpp:355:32:355:33 | it | | +| vector.cpp:355:32:355:33 | call to iterator [post update] | vector.cpp:354:56:354:57 | v4 | | +| vector.cpp:355:32:355:33 | call to iterator [post update] | vector.cpp:357:7:357:8 | v4 | | +| vector.cpp:355:32:355:33 | call to iterator [post update] | vector.cpp:401:1:401:1 | v4 | | +| vector.cpp:355:32:355:33 | it | vector.cpp:355:32:355:33 | call to iterator | | +| vector.cpp:355:32:355:33 | it [post update] | vector.cpp:354:56:354:57 | v4 | | +| vector.cpp:355:32:355:33 | it [post update] | vector.cpp:357:7:357:8 | v4 | | +| vector.cpp:355:32:355:33 | it [post update] | vector.cpp:401:1:401:1 | v4 | | +| vector.cpp:357:7:357:8 | ref arg v4 | vector.cpp:401:1:401:1 | v4 | | +| vector.cpp:359:34:359:35 | ref arg v5 | vector.cpp:361:7:361:8 | v5 | | +| vector.cpp:359:34:359:35 | ref arg v5 | vector.cpp:363:7:363:8 | v5 | | +| vector.cpp:359:34:359:35 | ref arg v5 | vector.cpp:401:1:401:1 | v5 | | +| vector.cpp:359:34:359:35 | v5 | vector.cpp:359:37:359:41 | call to begin | TAINT | +| vector.cpp:359:37:359:41 | call to begin | vector.cpp:360:3:360:4 | i5 | | +| vector.cpp:359:37:359:41 | call to begin | vector.cpp:362:3:362:4 | i5 | | +| vector.cpp:360:2:360:2 | call to operator* [post update] | vector.cpp:361:7:361:8 | v5 | | +| vector.cpp:360:2:360:2 | call to operator* [post update] | vector.cpp:363:7:363:8 | v5 | | +| vector.cpp:360:2:360:2 | call to operator* [post update] | vector.cpp:401:1:401:1 | v5 | | +| vector.cpp:360:2:360:15 | ... = ... | vector.cpp:360:2:360:2 | call to operator* [post update] | | +| vector.cpp:360:3:360:4 | i5 | vector.cpp:360:2:360:2 | call to operator* | TAINT | +| vector.cpp:360:8:360:13 | call to source | vector.cpp:360:2:360:2 | call to operator* [post update] | TAINT | +| vector.cpp:360:8:360:13 | call to source | vector.cpp:360:2:360:15 | ... = ... | | +| vector.cpp:361:7:361:8 | ref arg v5 | vector.cpp:363:7:363:8 | v5 | | +| vector.cpp:361:7:361:8 | ref arg v5 | vector.cpp:401:1:401:1 | v5 | | +| vector.cpp:362:2:362:2 | call to operator* [post update] | vector.cpp:363:7:363:8 | v5 | | +| vector.cpp:362:2:362:2 | call to operator* [post update] | vector.cpp:401:1:401:1 | v5 | | +| vector.cpp:362:2:362:8 | ... = ... | vector.cpp:362:2:362:2 | call to operator* [post update] | | +| vector.cpp:362:3:362:4 | i5 | vector.cpp:362:2:362:2 | call to operator* | TAINT | +| vector.cpp:362:8:362:8 | 1 | vector.cpp:362:2:362:2 | call to operator* [post update] | TAINT | +| vector.cpp:362:8:362:8 | 1 | vector.cpp:362:2:362:8 | ... = ... | | +| vector.cpp:363:7:363:8 | ref arg v5 | vector.cpp:401:1:401:1 | v5 | | +| vector.cpp:365:34:365:35 | ref arg v6 | vector.cpp:367:7:367:8 | v6 | | +| vector.cpp:365:34:365:35 | ref arg v6 | vector.cpp:368:2:368:3 | v6 | | +| vector.cpp:365:34:365:35 | ref arg v6 | vector.cpp:369:7:369:8 | v6 | | +| vector.cpp:365:34:365:35 | ref arg v6 | vector.cpp:401:1:401:1 | v6 | | +| vector.cpp:365:34:365:35 | v6 | vector.cpp:365:37:365:41 | call to begin | TAINT | +| vector.cpp:365:37:365:41 | call to begin | vector.cpp:366:3:366:4 | i6 | | +| vector.cpp:366:2:366:2 | call to operator* [post update] | vector.cpp:367:7:367:8 | v6 | | +| vector.cpp:366:2:366:2 | call to operator* [post update] | vector.cpp:368:2:368:3 | v6 | | +| vector.cpp:366:2:366:2 | call to operator* [post update] | vector.cpp:369:7:369:8 | v6 | | +| vector.cpp:366:2:366:2 | call to operator* [post update] | vector.cpp:401:1:401:1 | v6 | | +| vector.cpp:366:2:366:15 | ... = ... | vector.cpp:366:2:366:2 | call to operator* [post update] | | +| vector.cpp:366:3:366:4 | i6 | vector.cpp:366:2:366:2 | call to operator* | TAINT | +| vector.cpp:366:8:366:13 | call to source | vector.cpp:366:2:366:2 | call to operator* [post update] | TAINT | +| vector.cpp:366:8:366:13 | call to source | vector.cpp:366:2:366:15 | ... = ... | | +| vector.cpp:367:7:367:8 | ref arg v6 | vector.cpp:368:2:368:3 | v6 | | +| vector.cpp:367:7:367:8 | ref arg v6 | vector.cpp:369:7:369:8 | v6 | | +| vector.cpp:367:7:367:8 | ref arg v6 | vector.cpp:401:1:401:1 | v6 | | +| vector.cpp:368:2:368:3 | ref arg v6 | vector.cpp:369:7:369:8 | v6 | | +| vector.cpp:368:2:368:3 | ref arg v6 | vector.cpp:401:1:401:1 | v6 | | +| vector.cpp:368:7:368:26 | call to vector | vector.cpp:368:2:368:3 | ref arg v6 | TAINT | +| vector.cpp:368:7:368:26 | call to vector | vector.cpp:368:5:368:5 | call to operator= | TAINT | +| vector.cpp:369:7:369:8 | ref arg v6 | vector.cpp:401:1:401:1 | v6 | | +| vector.cpp:371:34:371:35 | ref arg v7 | vector.cpp:374:8:374:9 | v7 | | +| vector.cpp:371:34:371:35 | ref arg v7 | vector.cpp:377:8:377:9 | v7 | | +| vector.cpp:371:34:371:35 | ref arg v7 | vector.cpp:379:7:379:8 | v7 | | +| vector.cpp:371:34:371:35 | ref arg v7 | vector.cpp:401:1:401:1 | v7 | | +| vector.cpp:371:34:371:35 | v7 | vector.cpp:371:37:371:41 | call to begin | TAINT | +| vector.cpp:371:37:371:41 | call to begin | vector.cpp:373:4:373:5 | i7 | | +| vector.cpp:371:37:371:41 | call to begin | vector.cpp:376:4:376:5 | i7 | | +| vector.cpp:373:3:373:3 | call to operator* [post update] | vector.cpp:374:8:374:9 | v7 | | +| vector.cpp:373:3:373:3 | call to operator* [post update] | vector.cpp:379:7:379:8 | v7 | | +| vector.cpp:373:3:373:3 | call to operator* [post update] | vector.cpp:401:1:401:1 | v7 | | +| vector.cpp:373:3:373:16 | ... = ... | vector.cpp:373:3:373:3 | call to operator* [post update] | | +| vector.cpp:373:4:373:5 | i7 | vector.cpp:373:3:373:3 | call to operator* | TAINT | +| vector.cpp:373:9:373:14 | call to source | vector.cpp:373:3:373:3 | call to operator* [post update] | TAINT | +| vector.cpp:373:9:373:14 | call to source | vector.cpp:373:3:373:16 | ... = ... | | +| vector.cpp:374:8:374:9 | ref arg v7 | vector.cpp:379:7:379:8 | v7 | | +| vector.cpp:374:8:374:9 | ref arg v7 | vector.cpp:401:1:401:1 | v7 | | +| vector.cpp:376:3:376:3 | call to operator* [post update] | vector.cpp:377:8:377:9 | v7 | | +| vector.cpp:376:3:376:3 | call to operator* [post update] | vector.cpp:379:7:379:8 | v7 | | +| vector.cpp:376:3:376:3 | call to operator* [post update] | vector.cpp:401:1:401:1 | v7 | | +| vector.cpp:376:3:376:9 | ... = ... | vector.cpp:376:3:376:3 | call to operator* [post update] | | +| vector.cpp:376:4:376:5 | i7 | vector.cpp:376:3:376:3 | call to operator* | TAINT | +| vector.cpp:376:9:376:9 | 1 | vector.cpp:376:3:376:3 | call to operator* [post update] | TAINT | +| vector.cpp:376:9:376:9 | 1 | vector.cpp:376:3:376:9 | ... = ... | | +| vector.cpp:377:8:377:9 | ref arg v7 | vector.cpp:379:7:379:8 | v7 | | +| vector.cpp:377:8:377:9 | ref arg v7 | vector.cpp:401:1:401:1 | v7 | | +| vector.cpp:379:7:379:8 | ref arg v7 | vector.cpp:401:1:401:1 | v7 | | +| vector.cpp:381:34:381:35 | ref arg v8 | vector.cpp:383:7:383:8 | v8 | | +| vector.cpp:381:34:381:35 | ref arg v8 | vector.cpp:385:7:385:8 | v8 | | +| vector.cpp:381:34:381:35 | ref arg v8 | vector.cpp:401:1:401:1 | v8 | | +| vector.cpp:381:34:381:35 | v8 | vector.cpp:381:37:381:41 | call to begin | TAINT | +| vector.cpp:381:37:381:41 | call to begin | vector.cpp:382:3:382:4 | i8 | | +| vector.cpp:381:37:381:41 | call to begin | vector.cpp:384:3:384:4 | i8 | | +| vector.cpp:382:2:382:2 | call to operator* [post update] | vector.cpp:383:7:383:8 | v8 | | +| vector.cpp:382:2:382:2 | call to operator* [post update] | vector.cpp:385:7:385:8 | v8 | | +| vector.cpp:382:2:382:2 | call to operator* [post update] | vector.cpp:401:1:401:1 | v8 | | +| vector.cpp:382:2:382:15 | ... = ... | vector.cpp:382:2:382:2 | call to operator* [post update] | | +| vector.cpp:382:3:382:4 | i8 | vector.cpp:382:2:382:2 | call to operator* | TAINT | +| vector.cpp:382:8:382:13 | call to source | vector.cpp:382:2:382:2 | call to operator* [post update] | TAINT | +| vector.cpp:382:8:382:13 | call to source | vector.cpp:382:2:382:15 | ... = ... | | +| vector.cpp:383:7:383:8 | ref arg v8 | vector.cpp:385:7:385:8 | v8 | | +| vector.cpp:383:7:383:8 | ref arg v8 | vector.cpp:401:1:401:1 | v8 | | +| vector.cpp:384:2:384:2 | call to operator* [post update] | vector.cpp:385:7:385:8 | v8 | | +| vector.cpp:384:2:384:2 | call to operator* [post update] | vector.cpp:401:1:401:1 | v8 | | +| vector.cpp:384:2:384:8 | ... = ... | vector.cpp:384:2:384:2 | call to operator* [post update] | | +| vector.cpp:384:3:384:4 | i8 | vector.cpp:384:2:384:2 | call to operator* | TAINT | +| vector.cpp:384:8:384:8 | 1 | vector.cpp:384:2:384:2 | call to operator* [post update] | TAINT | +| vector.cpp:384:8:384:8 | 1 | vector.cpp:384:2:384:8 | ... = ... | | +| vector.cpp:385:7:385:8 | ref arg v8 | vector.cpp:401:1:401:1 | v8 | | +| vector.cpp:387:34:387:35 | ref arg v9 | vector.cpp:392:7:392:8 | v9 | | +| vector.cpp:387:34:387:35 | ref arg v9 | vector.cpp:401:1:401:1 | v9 | | +| vector.cpp:387:34:387:35 | v9 | vector.cpp:387:37:387:41 | call to begin | TAINT | +| vector.cpp:387:37:387:41 | call to begin | vector.cpp:389:3:389:4 | i9 | | +| vector.cpp:387:37:387:41 | call to begin | vector.cpp:390:31:390:32 | i9 | | +| vector.cpp:389:2:389:2 | call to operator* [post update] | vector.cpp:392:7:392:8 | v9 | | +| vector.cpp:389:2:389:2 | call to operator* [post update] | vector.cpp:401:1:401:1 | v9 | | +| vector.cpp:389:2:389:15 | ... = ... | vector.cpp:389:2:389:2 | call to operator* [post update] | | +| vector.cpp:389:3:389:4 | i9 | vector.cpp:389:2:389:2 | call to operator* | TAINT | +| vector.cpp:389:8:389:13 | call to source | vector.cpp:389:2:389:2 | call to operator* [post update] | TAINT | +| vector.cpp:389:8:389:13 | call to source | vector.cpp:389:2:389:15 | ... = ... | | +| vector.cpp:390:31:390:32 | call to iterator [post update] | vector.cpp:392:7:392:8 | v9 | | +| vector.cpp:390:31:390:32 | call to iterator [post update] | vector.cpp:401:1:401:1 | v9 | | +| vector.cpp:390:31:390:32 | i9 | vector.cpp:390:31:390:32 | call to iterator | | +| vector.cpp:390:31:390:32 | i9 [post update] | vector.cpp:392:7:392:8 | v9 | | +| vector.cpp:390:31:390:32 | i9 [post update] | vector.cpp:401:1:401:1 | v9 | | +| vector.cpp:392:7:392:8 | ref arg v9 | vector.cpp:401:1:401:1 | v9 | | +| vector.cpp:394:35:394:37 | ref arg v10 | vector.cpp:396:7:396:9 | v10 | | +| vector.cpp:394:35:394:37 | ref arg v10 | vector.cpp:401:1:401:1 | v10 | | +| vector.cpp:394:35:394:37 | v10 | vector.cpp:394:39:394:43 | call to begin | TAINT | +| vector.cpp:394:39:394:43 | call to begin | vector.cpp:395:33:395:35 | i10 | | +| vector.cpp:395:33:395:35 | call to iterator [post update] | vector.cpp:396:7:396:9 | v10 | | +| vector.cpp:395:33:395:35 | call to iterator [post update] | vector.cpp:401:1:401:1 | v10 | | +| vector.cpp:395:33:395:35 | i10 | vector.cpp:395:33:395:35 | call to iterator | | +| vector.cpp:395:33:395:35 | i10 [post update] | vector.cpp:396:7:396:9 | v10 | | +| vector.cpp:395:33:395:35 | i10 [post update] | vector.cpp:401:1:401:1 | v10 | | +| vector.cpp:396:7:396:9 | ref arg v10 | vector.cpp:401:1:401:1 | v10 | | +| vector.cpp:398:35:398:37 | ref arg v11 | vector.cpp:400:7:400:9 | v11 | | +| vector.cpp:398:35:398:37 | ref arg v11 | vector.cpp:401:1:401:1 | v11 | | +| vector.cpp:398:35:398:37 | v11 | vector.cpp:398:39:398:43 | call to begin | TAINT | +| vector.cpp:398:39:398:43 | call to begin | vector.cpp:399:33:399:35 | i11 | | +| vector.cpp:399:33:399:35 | call to iterator [post update] | vector.cpp:400:7:400:9 | v11 | | +| vector.cpp:399:33:399:35 | call to iterator [post update] | vector.cpp:401:1:401:1 | v11 | | +| vector.cpp:399:33:399:35 | i11 | vector.cpp:399:33:399:35 | call to iterator | | +| vector.cpp:399:33:399:35 | i11 [post update] | vector.cpp:400:7:400:9 | v11 | | +| vector.cpp:399:33:399:35 | i11 [post update] | vector.cpp:401:1:401:1 | v11 | | +| vector.cpp:400:7:400:9 | ref arg v11 | vector.cpp:401:1:401:1 | v11 | | diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected index 2eca13801c63..f91b718bdda2 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected @@ -375,16 +375,18 @@ | 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:330:10:330:15 | call to source | -| vector.cpp:357:7:357:8 | v5 | vector.cpp:356:8:356:13 | call to source | -| vector.cpp:359:7:359:8 | v5 | vector.cpp:356:8:356:13 | call to source | -| vector.cpp:363:7:363:8 | v6 | vector.cpp:362:8:362:13 | call to source | -| vector.cpp:365:7:365:8 | v6 | vector.cpp:362:8:362:13 | call to source | -| vector.cpp:370:8:370:9 | v7 | vector.cpp:369:9:369:14 | call to source | -| vector.cpp:375:7:375:8 | v7 | vector.cpp:369:9:369:14 | call to source | -| vector.cpp:379:7:379:8 | v8 | vector.cpp:378:8:378:13 | call to source | -| vector.cpp:381:7:381:8 | v8 | vector.cpp:378:8:378:13 | call to source | -| vector.cpp:388:7:388:8 | v9 | vector.cpp:330:10:330:15 | call to source | -| vector.cpp:388:7:388:8 | v9 | vector.cpp:385:8:385:13 | call to source | +| vector.cpp:342:7:342:8 | v1 | vector.cpp:341:8:341:13 | call to source | +| vector.cpp:347:7:347:8 | v2 | vector.cpp:345:9:345:14 | call to source | +| vector.cpp:357:7:357:8 | v4 | vector.cpp:330:10:330:15 | call to source | +| vector.cpp:361:7:361:8 | v5 | vector.cpp:360:8:360:13 | call to source | +| vector.cpp:363:7:363:8 | v5 | vector.cpp:360:8:360:13 | call to source | +| vector.cpp:367:7:367:8 | v6 | vector.cpp:366:8:366:13 | call to source | +| vector.cpp:369:7:369:8 | v6 | vector.cpp:366:8:366:13 | call to source | +| vector.cpp:374:8:374:9 | v7 | vector.cpp:373:9:373:14 | call to source | +| vector.cpp:379:7:379:8 | v7 | vector.cpp:373:9:373:14 | call to source | +| vector.cpp:383:7:383:8 | v8 | vector.cpp:382:8:382:13 | call to source | +| vector.cpp:385:7:385:8 | v8 | vector.cpp:382:8:382:13 | call to source | +| vector.cpp:392:7:392:8 | v9 | vector.cpp:330:10:330:15 | call to source | +| vector.cpp:392:7:392:8 | v9 | vector.cpp:389:8:389:13 | call to source | +| vector.cpp:396:7:396:9 | v10 | vector.cpp:399:38:399:43 | call to source | +| vector.cpp:400:7:400:9 | v11 | vector.cpp:399:38:399:43 | call to source | diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected index db6bf0f3cf0c..6397c1d78300 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected @@ -300,16 +300,18 @@ | 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:330:10:330:15 | AST only | -| vector.cpp:357:7:357:8 | vector.cpp:356:8:356:13 | AST only | -| vector.cpp:359:7:359:8 | vector.cpp:356:8:356:13 | AST only | -| vector.cpp:363:7:363:8 | vector.cpp:362:8:362:13 | AST only | -| vector.cpp:365:7:365:8 | vector.cpp:362:8:362:13 | AST only | -| vector.cpp:370:8:370:9 | vector.cpp:369:9:369:14 | AST only | -| vector.cpp:375:7:375:8 | vector.cpp:369:9:369:14 | AST only | -| vector.cpp:379:7:379:8 | vector.cpp:378:8:378:13 | AST only | -| vector.cpp:381:7:381:8 | vector.cpp:378:8:378:13 | AST only | -| vector.cpp:388:7:388:8 | vector.cpp:330:10:330:15 | AST only | -| vector.cpp:388:7:388:8 | vector.cpp:385:8:385:13 | AST only | +| vector.cpp:342:7:342:8 | vector.cpp:341:8:341:13 | AST only | +| vector.cpp:347:7:347:8 | vector.cpp:345:9:345:14 | AST only | +| vector.cpp:357:7:357:8 | vector.cpp:330:10:330:15 | AST only | +| vector.cpp:361:7:361:8 | vector.cpp:360:8:360:13 | AST only | +| vector.cpp:363:7:363:8 | vector.cpp:360:8:360:13 | AST only | +| vector.cpp:367:7:367:8 | vector.cpp:366:8:366:13 | AST only | +| vector.cpp:369:7:369:8 | vector.cpp:366:8:366:13 | AST only | +| vector.cpp:374:8:374:9 | vector.cpp:373:9:373:14 | AST only | +| vector.cpp:379:7:379:8 | vector.cpp:373:9:373:14 | AST only | +| vector.cpp:383:7:383:8 | vector.cpp:382:8:382:13 | AST only | +| vector.cpp:385:7:385:8 | vector.cpp:382:8:382:13 | AST only | +| vector.cpp:392:7:392:8 | vector.cpp:330:10:330:15 | AST only | +| vector.cpp:392:7:392:8 | vector.cpp:389:8:389:13 | AST only | +| vector.cpp:396:7:396:9 | vector.cpp:399:38:399:43 | AST only | +| vector.cpp:400:7:400:9 | vector.cpp:399:38:399:43 | AST only | diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp index 92cd5f4c9f53..0cc6570a175f 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp @@ -330,8 +330,12 @@ void taint_vector_output_iterator(std::vector::iterator iter) { *iter = source(); } +void vector_iterator_assign_wrapper(std::vector::iterator iter, int i) { + *iter = i; +} + void test_vector_output_iterator(int b) { - std::vector v1(10), v2(10), v3(10), v4(10), v5(10), v6(10), v7(10), v8(10), v9(10); + std::vector v1(10), v2(10), v3(10), v4(10), v5(10), v6(10), v7(10), v8(10), v9(10), v10(10), v11(10); std::vector::iterator i1 = v1.begin(); *i1 = source(); @@ -386,4 +390,12 @@ void test_vector_output_iterator(int b) { taint_vector_output_iterator(i9); sink(v9); + + std::vector::iterator i10 = v10.begin(); + vector_iterator_assign_wrapper(i10, 10); + sink(v10); // FALSE POSITIVE + + std::vector::iterator i11 = v11.begin(); + vector_iterator_assign_wrapper(i11, source()); + sink(v11); // tainted [NOT DETECTED by IR] } From 9e3bfe1968c3c39339bf638ce47a709c9a1effc4 Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Mon, 21 Sep 2020 16:17:16 -0700 Subject: [PATCH 16/25] C++: Fix iterator flow context sensitivity --- .../cpp/dataflow/internal/DataFlowPrivate.qll | 6 ++- .../cpp/dataflow/internal/DataFlowUtil.qll | 42 ++++++++++++------- .../code/cpp/dataflow/internal/FlowVar.qll | 7 ++++ .../dataflow/internal/TaintTrackingUtil.qll | 5 --- .../dataflow/taint-tests/taint.expected | 1 - .../dataflow/taint-tests/test_diff.expected | 1 - 6 files changed, 37 insertions(+), 25 deletions(-) diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll index 42c31bca69c8..e737f8b2d946 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll @@ -1,6 +1,8 @@ private import cpp private import DataFlowUtil private import DataFlowDispatch +private import FlowVar + /** Gets the instance argument of a non-static call. */ private Node getInstanceArgument(Call call) { @@ -106,7 +108,7 @@ private class ExprOutNode extends OutNode, ExprNode { override DataFlowCall getCall() { result = this.getExpr() } } -private class RefOutNode extends OutNode, DefinitionByReferenceNode { +private class RefOutNode extends OutNode, DefinitionByReferenceOrIteratorNode { /** Gets the underlying call. */ override DataFlowCall getCall() { result = this.getArgument().getParent() } } @@ -120,7 +122,7 @@ OutNode getAnOutNode(DataFlowCall call, ReturnKind kind) { kind = TNormalReturnKind() or exists(int i | - result.asDefiningArgument() = call.getArgument(i) and + result.(DefinitionByReferenceOrIteratorNode).getArgument() = call.getArgument(i) and kind = TRefReturnKind(i) ) } diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll index 963f1a178261..25a37f9db0f2 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll @@ -182,29 +182,23 @@ class ImplicitParameterNode extends ParameterNode, TInstanceParameterNode { override predicate isParameterOf(Function fun, int i) { f = fun and i = -1 } } -/** - * A node that represents the value of a variable after a function call that - * may have changed the variable because it's passed by reference. - * - * A typical example would be a call `f(&x)`. Firstly, there will be flow into - * `x` from previous definitions of `x`. Secondly, there will be a - * `DefinitionByReferenceNode` to represent the value of `x` after the call has - * returned. This node will have its `getArgument()` equal to `&x`. - */ -class DefinitionByReferenceNode extends PartialDefinitionNode { +class DefinitionByReferenceOrIteratorNode extends PartialDefinitionNode { Expr inner; Expr argument; - DefinitionByReferenceNode() { - this.getPartialDefinition().(DefinitionByReference).definesExpressions(inner, argument) + DefinitionByReferenceOrIteratorNode() { + this.getPartialDefinition().definesExpressions(inner, argument) and + ( + this.getPartialDefinition() instanceof DefinitionByReference + or + this.getPartialDefinition() instanceof DefinitionByIterator + ) } override Function getFunction() { result = inner.getEnclosingFunction() } override Type getType() { result = inner.getType() } - override string toString() { result = "ref arg " + argument.toString() } - override Location getLocation() { result = argument.getLocation() } override ExprNode getPreUpdateNode() { result.getExpr() = argument } @@ -221,6 +215,22 @@ class DefinitionByReferenceNode extends PartialDefinitionNode { } } + +/** + * A node that represents the value of a variable after a function call that + * may have changed the variable because it's passed by reference. + * + * A typical example would be a call `f(&x)`. Firstly, there will be flow into + * `x` from previous definitions of `x`. Secondly, there will be a + * `DefinitionByReferenceNode` to represent the value of `x` after the call has + * returned. This node will have its `getArgument()` equal to `&x`. + */ +class DefinitionByReferenceNode extends DefinitionByReferenceOrIteratorNode { + override VariablePartialDefinition pd; + + override string toString() { result = "ref arg " + argument.toString() } +} + /** * The value of an uninitialized local variable, viewed as a node in a data * flow graph. @@ -551,10 +561,10 @@ predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) { or // In `f(&x->a)`, this step provides the flow from post-`&` to post-`x->a`, // from which there is field flow to `x` via reverse read. - exists(VariablePartialDefinition def, Expr inner, Expr outer | + exists(PartialDefinition def, Expr inner, Expr outer | def.definesExpressions(inner, outer) and inner = nodeTo.(InnerPartialDefinitionNode).getPreUpdateNode().asExpr() and - outer = nodeFrom.(VariablePartialDefinitionNode).getPreUpdateNode().asExpr() + outer = nodeFrom.(PartialDefinitionNode).getPreUpdateNode().asExpr() ) or // Reverse flow: data that flows from the post-update node of a reference diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll index 13f11f8b2750..15c15595c4f5 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll @@ -243,6 +243,13 @@ private module PartialDefinitions { } } + /** + * A partial definition that's a definition by reference. + */ + class DefinitionByIterator extends IteratorPartialDefinition { + DefinitionByIterator() { exists(Call c | this = c.getAnArgument() or this = c.getQualifier()) } + } + /** * A partial definition that's a definition by reference. */ diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll index 3190d3e9eba3..17cb9b881046 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll @@ -31,11 +31,6 @@ predicate localTaintStep(DataFlow::Node src, DataFlow::Node sink) { */ predicate defaultAdditionalTaintStep(DataFlow::Node src, DataFlow::Node sink) { localAdditionalTaintStep(src, sink) - or - exists(FunctionCall call, int i | - sink.(DataFlow::IteratorPartialDefinitionNode).getPartialDefinition().definesExpressions(_, call.getArgument(i)) and - src.(DataFlow::RefParameterFinalValueNode).getParameter() = call.getTarget().getParameter(i) - ) } /** diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected index f91b718bdda2..033cd47145b1 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected @@ -388,5 +388,4 @@ | vector.cpp:385:7:385:8 | v8 | vector.cpp:382:8:382:13 | call to source | | vector.cpp:392:7:392:8 | v9 | vector.cpp:330:10:330:15 | call to source | | vector.cpp:392:7:392:8 | v9 | vector.cpp:389:8:389:13 | call to source | -| vector.cpp:396:7:396:9 | v10 | vector.cpp:399:38:399:43 | call to source | | vector.cpp:400:7:400:9 | v11 | vector.cpp:399:38:399:43 | call to source | diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected index 6397c1d78300..3dc9b717e073 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected @@ -313,5 +313,4 @@ | vector.cpp:385:7:385:8 | vector.cpp:382:8:382:13 | AST only | | vector.cpp:392:7:392:8 | vector.cpp:330:10:330:15 | AST only | | vector.cpp:392:7:392:8 | vector.cpp:389:8:389:13 | AST only | -| vector.cpp:396:7:396:9 | vector.cpp:399:38:399:43 | AST only | | vector.cpp:400:7:400:9 | vector.cpp:399:38:399:43 | AST only | From 772a51508f09f8b8b7d2e256db11dab0fbfd33f6 Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Mon, 21 Sep 2020 16:19:41 -0700 Subject: [PATCH 17/25] C++: Update test comment --- cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp index 0cc6570a175f..b5dad8119989 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp @@ -393,7 +393,7 @@ void test_vector_output_iterator(int b) { std::vector::iterator i10 = v10.begin(); vector_iterator_assign_wrapper(i10, 10); - sink(v10); // FALSE POSITIVE + sink(v10); std::vector::iterator i11 = v11.begin(); vector_iterator_assign_wrapper(i11, source()); From 774dcc7c5292696d69e3b5a1726b7aa164028450 Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Wed, 23 Sep 2020 15:29:37 -0700 Subject: [PATCH 18/25] C++: New model class for iterator op* and op[] --- .../dataflow/internal/TaintTrackingUtil.qll | 10 ++-------- .../cpp/models/implementations/Iterator.qll | 14 +++++++++++--- .../code/cpp/models/interfaces/Iterator.qll | 19 +++++++++++++++++++ 3 files changed, 32 insertions(+), 11 deletions(-) create mode 100644 cpp/ql/src/semmle/code/cpp/models/interfaces/Iterator.qll diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll index 17cb9b881046..1ef340c4f213 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll @@ -10,7 +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 import semmle.code.cpp.models.interfaces.Iterator private module DataFlow { import semmle.code.cpp.dataflow.internal.DataFlowUtil @@ -264,10 +264,4 @@ private predicate exprToPartialDefinitionStep(Expr exprIn, Expr exprOut) { ) } -private predicate iteratorDereference(Call c) { - c.getTarget() instanceof IteratorArrayMemberOperator - or - c.getTarget() instanceof IteratorPointerDereferenceMemberOperator - or - c.getTarget() instanceof IteratorPointerDereferenceOperator -} +private predicate iteratorDereference(Call c) { c.getTarget() instanceof IteratorReferenceFunction } diff --git a/cpp/ql/src/semmle/code/cpp/models/implementations/Iterator.qll b/cpp/ql/src/semmle/code/cpp/models/implementations/Iterator.qll index 93a04d5ef900..c1b8e24e7db2 100644 --- a/cpp/ql/src/semmle/code/cpp/models/implementations/Iterator.qll +++ b/cpp/ql/src/semmle/code/cpp/models/implementations/Iterator.qll @@ -8,6 +8,7 @@ import cpp import semmle.code.cpp.models.interfaces.Taint import semmle.code.cpp.models.interfaces.DataFlow +import semmle.code.cpp.models.interfaces.Iterator /** * An instantiation of the `std::iterator_traits` template. @@ -80,7 +81,7 @@ private FunctionInput getIteratorArgumentInput(Operator op, int index) { /** * A non-member prefix `operator*` function for an iterator type. */ -class IteratorPointerDereferenceOperator extends Operator, TaintFunction { +class IteratorPointerDereferenceOperator extends Operator, TaintFunction, IteratorReferenceFunction { FunctionInput iteratorInput; IteratorPointerDereferenceOperator() { @@ -92,6 +93,8 @@ class IteratorPointerDereferenceOperator extends Operator, TaintFunction { input = iteratorInput and output.isReturnValue() } + + override FunctionInput getIteratorInput() { result = iteratorInput } } /** @@ -169,12 +172,15 @@ class IteratorAssignArithmeticOperator extends Operator, DataFlowFunction, Taint /** * A prefix `operator*` member function for an iterator type. */ -class IteratorPointerDereferenceMemberOperator extends MemberFunction, TaintFunction { +class IteratorPointerDereferenceMemberOperator extends MemberFunction, TaintFunction, + IteratorReferenceFunction { IteratorPointerDereferenceMemberOperator() { this.hasName("operator*") and this.getDeclaringType() instanceof Iterator } + override FunctionInput getIteratorInput() { result.isQualifierObject() } + override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { input.isQualifierObject() and output.isReturnValue() @@ -260,7 +266,7 @@ class IteratorAssignArithmeticMemberOperator extends MemberFunction, DataFlowFun /** * An `operator[]` member function of an iterator class. */ -class IteratorArrayMemberOperator extends MemberFunction, TaintFunction { +class IteratorArrayMemberOperator extends MemberFunction, TaintFunction, IteratorReferenceFunction { IteratorArrayMemberOperator() { this.hasName("operator[]") and this.getDeclaringType() instanceof Iterator @@ -270,6 +276,8 @@ class IteratorArrayMemberOperator extends MemberFunction, TaintFunction { input.isQualifierObject() and output.isReturnValue() } + + override FunctionInput getIteratorInput() { result.isQualifierObject() } } /** diff --git a/cpp/ql/src/semmle/code/cpp/models/interfaces/Iterator.qll b/cpp/ql/src/semmle/code/cpp/models/interfaces/Iterator.qll new file mode 100644 index 000000000000..ea9ce04e5301 --- /dev/null +++ b/cpp/ql/src/semmle/code/cpp/models/interfaces/Iterator.qll @@ -0,0 +1,19 @@ +/** + * Provides an abstract class for accurate modeling of flow through output + * iterators. To use this QL library, create a QL class extending + * `IteratorReferenceFunction` with a characteristic predicate that selects the + * function or set of functions you are modeling. Within that class, override + * the predicates provided by `AliasFunction` to match the flow within that + * function. + */ + +import cpp +import semmle.code.cpp.models.Models + +/** + * A function which takes an iterator argument and returns a reference that + * can be used to write to the iterator's underlying collection. + */ +abstract class IteratorReferenceFunction extends Function { + abstract FunctionInput getIteratorInput(); +} From 89332ca3037ac3b8c0c664cfe0ad90f9e44a421c Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Wed, 23 Sep 2020 15:29:51 -0700 Subject: [PATCH 19/25] C++: autoformat --- cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll | 1 - 1 file changed, 1 deletion(-) diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll index e737f8b2d946..4562eb3fd194 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll @@ -3,7 +3,6 @@ private import DataFlowUtil private import DataFlowDispatch private import FlowVar - /** Gets the instance argument of a non-static call. */ private Node getInstanceArgument(Call call) { result.asExpr() = call.getQualifier() From 094b06ec2accc225ba57df0a1686e972d700d252 Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Thu, 24 Sep 2020 10:37:38 -0700 Subject: [PATCH 20/25] C++: remove unneeded predicate --- .../src/semmle/code/cpp/models/implementations/Iterator.qll | 6 ------ cpp/ql/src/semmle/code/cpp/models/interfaces/Iterator.qll | 1 - 2 files changed, 7 deletions(-) diff --git a/cpp/ql/src/semmle/code/cpp/models/implementations/Iterator.qll b/cpp/ql/src/semmle/code/cpp/models/implementations/Iterator.qll index c1b8e24e7db2..ded937d53123 100644 --- a/cpp/ql/src/semmle/code/cpp/models/implementations/Iterator.qll +++ b/cpp/ql/src/semmle/code/cpp/models/implementations/Iterator.qll @@ -93,8 +93,6 @@ class IteratorPointerDereferenceOperator extends Operator, TaintFunction, Iterat input = iteratorInput and output.isReturnValue() } - - override FunctionInput getIteratorInput() { result = iteratorInput } } /** @@ -179,8 +177,6 @@ class IteratorPointerDereferenceMemberOperator extends MemberFunction, TaintFunc this.getDeclaringType() instanceof Iterator } - override FunctionInput getIteratorInput() { result.isQualifierObject() } - override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { input.isQualifierObject() and output.isReturnValue() @@ -276,8 +272,6 @@ class IteratorArrayMemberOperator extends MemberFunction, TaintFunction, Iterato input.isQualifierObject() and output.isReturnValue() } - - override FunctionInput getIteratorInput() { result.isQualifierObject() } } /** diff --git a/cpp/ql/src/semmle/code/cpp/models/interfaces/Iterator.qll b/cpp/ql/src/semmle/code/cpp/models/interfaces/Iterator.qll index ea9ce04e5301..1086e0889796 100644 --- a/cpp/ql/src/semmle/code/cpp/models/interfaces/Iterator.qll +++ b/cpp/ql/src/semmle/code/cpp/models/interfaces/Iterator.qll @@ -15,5 +15,4 @@ import semmle.code.cpp.models.Models * can be used to write to the iterator's underlying collection. */ abstract class IteratorReferenceFunction extends Function { - abstract FunctionInput getIteratorInput(); } From ca06637de0d4adaeb27286e8385ad42073dcec4f Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Thu, 24 Sep 2020 10:40:45 -0700 Subject: [PATCH 21/25] C++: add qldoc comment --- .../semmle/code/cpp/dataflow/internal/DataFlowUtil.qll | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll index 25a37f9db0f2..9bbedfc16a86 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll @@ -182,6 +182,13 @@ class ImplicitParameterNode extends ParameterNode, TInstanceParameterNode { override predicate isParameterOf(Function fun, int i) { f = fun and i = -1 } } +/** + * INTERNAL: do not use. + * + * A node that represents the value of a variable after a function call that + * may have changed the variable because it's passed by reference or because an + * iterator for it was passed by value or by reference. + */ class DefinitionByReferenceOrIteratorNode extends PartialDefinitionNode { Expr inner; Expr argument; @@ -215,7 +222,6 @@ class DefinitionByReferenceOrIteratorNode extends PartialDefinitionNode { } } - /** * A node that represents the value of a variable after a function call that * may have changed the variable because it's passed by reference. From 46ff4d524fe3ff18b76a006e099fab12072a903e Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Thu, 24 Sep 2020 14:54:31 -0700 Subject: [PATCH 22/25] C++: autoformat --- cpp/ql/src/semmle/code/cpp/models/interfaces/Iterator.qll | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cpp/ql/src/semmle/code/cpp/models/interfaces/Iterator.qll b/cpp/ql/src/semmle/code/cpp/models/interfaces/Iterator.qll index 1086e0889796..de6977765253 100644 --- a/cpp/ql/src/semmle/code/cpp/models/interfaces/Iterator.qll +++ b/cpp/ql/src/semmle/code/cpp/models/interfaces/Iterator.qll @@ -14,5 +14,4 @@ import semmle.code.cpp.models.Models * A function which takes an iterator argument and returns a reference that * can be used to write to the iterator's underlying collection. */ -abstract class IteratorReferenceFunction extends Function { -} +abstract class IteratorReferenceFunction extends Function { } From 9240256a9f0910b6aac8da05c087d6208f353f7f Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Fri, 25 Sep 2020 11:55:39 -0700 Subject: [PATCH 23/25] C++: fix QLDoc --- cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll index 15c15595c4f5..40a671429f33 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll @@ -244,7 +244,7 @@ private module PartialDefinitions { } /** - * A partial definition that's a definition by reference. + * A partial definition that's a definition via an output iterator. */ class DefinitionByIterator extends IteratorPartialDefinition { DefinitionByIterator() { exists(Call c | this = c.getAnArgument() or this = c.getQualifier()) } From 27dc49ff7a6f0e1c0724367b628291b97f6b4407 Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Fri, 25 Sep 2020 17:49:01 -0700 Subject: [PATCH 24/25] C++: Fix performance issue in PartialDefinition --- cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll index 40a671429f33..50395dbaafc0 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll @@ -112,8 +112,6 @@ private module PartialDefinitions { abstract class PartialDefinition extends Expr { ControlFlowNode node; - PartialDefinition() { not this instanceof Conversion } - abstract deprecated predicate partiallyDefines(Variable v); abstract deprecated predicate partiallyDefinesThis(ThisExpr e); @@ -161,6 +159,7 @@ private module PartialDefinitions { IteratorPartialDefinition() { exists(Expr convertedInner | + not this instanceof Conversion and valueToUpdate(convertedInner, this.getFullyConverted(), node) and innerDefinedExpr = convertedInner.getUnconverted() and ( @@ -212,6 +211,7 @@ private module PartialDefinitions { Expr innerDefinedExpr; VariablePartialDefinition() { + not this instanceof Conversion and exists(Expr convertedInner | valueToUpdate(convertedInner, this.getFullyConverted(), node) and innerDefinedExpr = convertedInner.getUnconverted() From 68f6d9332523df633415e8550818a760c57f985b Mon Sep 17 00:00:00 2001 From: Jonas Jensen Date: Wed, 30 Sep 2020 09:49:56 +0200 Subject: [PATCH 25/25] C++: Autoformat fixup --- cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll index 9bbedfc16a86..09409eb30f2a 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll @@ -184,7 +184,7 @@ class ImplicitParameterNode extends ParameterNode, TInstanceParameterNode { /** * INTERNAL: do not use. - * + * * A node that represents the value of a variable after a function call that * may have changed the variable because it's passed by reference or because an * iterator for it was passed by value or by reference.