Skip to content

Commit a1a441d

Browse files
author
Robert Marsh
committed
C++: output iterator flow through operator= models
1 parent f3843b8 commit a1a441d

File tree

4 files changed

+55
-0
lines changed

4 files changed

+55
-0
lines changed

cpp/ql/src/semmle/code/cpp/models/implementations/Iterator.qll

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,20 @@ private FunctionInput getIteratorArgumentInput(Operator op, int index) {
7878
)
7979
}
8080

81+
private FunctionOutput getIteratorArgumentOutput(Operator op, int index) {
82+
exists(Type t |
83+
t =
84+
op
85+
.getACallToThisFunction()
86+
.getArgument(index)
87+
.getExplicitlyConverted()
88+
.getType()
89+
.stripTopLevelSpecifiers()
90+
|
91+
result.isParameterDeref(index) // TODO: does this work with an rvalue reference?
92+
)
93+
}
94+
8195
/**
8296
* A non-member prefix `operator*` function for an iterator type.
8397
*/
@@ -92,6 +106,9 @@ class IteratorPointerDereferenceOperator extends Operator, TaintFunction, Iterat
92106
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
93107
input = iteratorInput and
94108
output.isReturnValue()
109+
or
110+
input.isReturnValueDeref() and
111+
output = getIteratorArgumentOutput(this, 0)
95112
}
96113
}
97114

@@ -180,6 +197,9 @@ class IteratorPointerDereferenceMemberOperator extends MemberFunction, TaintFunc
180197
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
181198
input.isQualifierObject() and
182199
output.isReturnValue()
200+
or
201+
input.isReturnValueDeref() and
202+
output.isQualifierObject()
183203
}
184204
}
185205

@@ -274,6 +294,27 @@ class IteratorArrayMemberOperator extends MemberFunction, TaintFunction, Iterato
274294
}
275295
}
276296

297+
/**
298+
* An `operator=` member function of an iterator class that is not a copy or move assignment
299+
* operator.
300+
*
301+
* The `hasTaintFlow` override provides flow through output iterators that return themselves with
302+
* `operator*` and use their own `operator=` to assign to the container.
303+
*/
304+
class IteratorAssignmentMemberOperator extends MemberFunction, TaintFunction {
305+
IteratorAssignmentMemberOperator() {
306+
this.hasName("operator=") and
307+
this.getDeclaringType() instanceof Iterator and
308+
not this instanceof CopyAssignmentOperator and
309+
not this instanceof MoveAssignmentOperator
310+
}
311+
312+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
313+
input.isParameter(0) and
314+
output.isQualifierObject()
315+
}
316+
}
317+
277318
/**
278319
* A `begin` or `end` member function, or a related member function, that
279320
* returns an iterator.

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7135,8 +7135,13 @@
71357135
| vector.cpp:427:13:427:30 | call to back_inserter | vector.cpp:428:4:428:5 | it | |
71367136
| vector.cpp:427:32:427:34 | ref arg out | vector.cpp:429:8:429:10 | out | |
71377137
| vector.cpp:427:32:427:34 | ref arg out | vector.cpp:430:2:430:2 | out | |
7138+
| vector.cpp:428:3:428:3 | ref arg call to operator* | vector.cpp:428:6:428:6 | ref arg call to operator++ | TAINT |
7139+
| vector.cpp:428:3:428:3 | ref arg call to operator* | vector.cpp:429:8:429:10 | out | |
7140+
| vector.cpp:428:3:428:3 | ref arg call to operator* | vector.cpp:430:2:430:2 | out | |
71387141
| vector.cpp:428:4:428:5 | it | vector.cpp:428:6:428:6 | call to operator++ | |
71397142
| vector.cpp:428:6:428:6 | call to operator++ | vector.cpp:428:3:428:3 | call to operator* | TAINT |
7143+
| vector.cpp:428:6:428:6 | ref arg call to operator++ | vector.cpp:428:4:428:5 | ref arg it | |
7144+
| vector.cpp:428:11:428:36 | call to basic_string | vector.cpp:428:3:428:3 | ref arg call to operator* | TAINT |
71407145
| vector.cpp:428:23:428:35 | source_string | vector.cpp:428:11:428:36 | call to basic_string | TAINT |
71417146
| vector.cpp:429:8:429:10 | ref arg out | vector.cpp:430:2:430:2 | out | |
71427147
| vector.cpp:433:20:433:22 | call to vector | vector.cpp:434:32:434:34 | out | |
@@ -7145,6 +7150,11 @@
71457150
| vector.cpp:434:13:434:30 | call to back_inserter | vector.cpp:435:4:435:5 | it | |
71467151
| vector.cpp:434:32:434:34 | ref arg out | vector.cpp:436:8:436:10 | out | |
71477152
| vector.cpp:434:32:434:34 | ref arg out | vector.cpp:437:2:437:2 | out | |
7153+
| vector.cpp:435:3:435:3 | ref arg call to operator* | vector.cpp:435:6:435:6 | ref arg call to operator++ | TAINT |
7154+
| vector.cpp:435:3:435:3 | ref arg call to operator* | vector.cpp:436:8:436:10 | out | |
7155+
| vector.cpp:435:3:435:3 | ref arg call to operator* | vector.cpp:437:2:437:2 | out | |
71487156
| vector.cpp:435:4:435:5 | it | vector.cpp:435:6:435:6 | call to operator++ | |
71497157
| vector.cpp:435:6:435:6 | call to operator++ | vector.cpp:435:3:435:3 | call to operator* | TAINT |
7158+
| vector.cpp:435:6:435:6 | ref arg call to operator++ | vector.cpp:435:4:435:5 | ref arg it | |
7159+
| vector.cpp:435:11:435:16 | call to source | vector.cpp:435:3:435:3 | ref arg call to operator* | TAINT |
71507160
| vector.cpp:436:8:436:10 | ref arg out | vector.cpp:437:2:437:2 | out | |

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,3 +657,5 @@
657657
| vector.cpp:409:7:409:9 | v13 | vector.cpp:408:11:408:16 | call to source |
658658
| vector.cpp:414:7:414:9 | v14 | vector.cpp:413:11:413:16 | call to source |
659659
| vector.cpp:422:8:422:10 | out | vector.cpp:417:33:417:45 | source_string |
660+
| vector.cpp:429:8:429:10 | out | vector.cpp:417:33:417:45 | source_string |
661+
| vector.cpp:436:8:436:10 | out | vector.cpp:435:11:435:16 | call to source |

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,3 +383,5 @@
383383
| vector.cpp:409:7:409:9 | vector.cpp:408:11:408:16 | AST only |
384384
| vector.cpp:414:7:414:9 | vector.cpp:413:11:413:16 | AST only |
385385
| vector.cpp:422:8:422:10 | vector.cpp:417:33:417:45 | AST only |
386+
| vector.cpp:429:8:429:10 | vector.cpp:417:33:417:45 | AST only |
387+
| vector.cpp:436:8:436:10 | vector.cpp:435:11:435:16 | AST only |

0 commit comments

Comments
 (0)