Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 35 additions & 34 deletions cpp/ql/src/semmle/code/cpp/models/implementations/Iterator.qll
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import semmle.code.cpp.models.interfaces.Iterator
*/
private class IteratorTraits extends Class {
IteratorTraits() {
this.hasQualifiedName("std", "iterator_traits") and
this.hasQualifiedName(["std", "bsl"], "iterator_traits") and
not this instanceof TemplateClass and
exists(TypedefType t |
this.getAMember() = t and
Expand All @@ -26,6 +26,14 @@ private class IteratorTraits extends Class {
Type getIteratorType() { result = this.getTemplateArgument(0) }
}

/**
* A type that is deduced to be an iterator because there is a corresponding
* `std::iterator_traits` instantiation for it.
*/
private class IteratorByTraits extends Iterator {
IteratorByTraits() { exists(IteratorTraits it | it.getIteratorType() = this) }
}

/**
* A type which has the typedefs expected for an iterator.
*/
Expand All @@ -36,25 +44,21 @@ private class IteratorByTypedefs extends Iterator, Class {
this.getAMember().(TypedefType).hasName("pointer") and
this.getAMember().(TypedefType).hasName("reference") and
this.getAMember().(TypedefType).hasName("iterator_category") and
not this.hasQualifiedName("std", "iterator_traits")
not this.hasQualifiedName(["std", "bsl"], "iterator_traits")
}
}

/**
* The `std::iterator` class.
*/
private class StdIterator extends Iterator, Class {
StdIterator() { this.hasQualifiedName("std", "iterator") }
StdIterator() { this.hasQualifiedName(["std", "bsl"], "iterator") }
}

/**
* A type that is deduced to be an iterator because there is a corresponding
* `std::iterator_traits` instantiation for it.
* Gets the `FunctionInput` corresponding to an iterator parameter to
* user-defined operator `op`, at `index`.
*/
private class IteratorByTraits extends Iterator {
IteratorByTraits() { exists(IteratorTraits it | it.getIteratorType() = this) }
}

private FunctionInput getIteratorArgumentInput(Operator op, int index) {
exists(Type t |
t =
Expand Down Expand Up @@ -155,17 +159,21 @@ private class IteratorSubOperator extends Operator, TaintFunction {
private class IteratorAssignArithmeticOperator extends Operator, DataFlowFunction, TaintFunction {
IteratorAssignArithmeticOperator() {
this.hasName(["operator+=", "operator-="]) and
this.getDeclaringType() instanceof Iterator
exists(getIteratorArgumentInput(this, 0))
}

override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
input.isParameter(0) and
output.isReturnValue()
or
input.isParameterDeref(0) and output.isReturnValueDeref()
}

override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isParameterDeref(0) and output.isReturnValueDeref()
or
// reverse flow from returned reference to the object referenced by the first parameter
input.isReturnValueDeref() and
output.isParameterDeref(0)
or
input.isParameterDeref(1) and
output.isParameterDeref(0)
}
Expand All @@ -177,8 +185,7 @@ private class IteratorAssignArithmeticOperator extends Operator, DataFlowFunctio
class IteratorPointerDereferenceMemberOperator extends MemberFunction, TaintFunction,
IteratorReferenceFunction {
IteratorPointerDereferenceMemberOperator() {
this.hasName("operator*") and
this.getDeclaringType() instanceof Iterator
this.getClassAndName("operator*") instanceof Iterator
}

override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
Expand All @@ -195,8 +202,7 @@ class IteratorPointerDereferenceMemberOperator extends MemberFunction, TaintFunc
*/
private class IteratorCrementMemberOperator extends MemberFunction, DataFlowFunction, TaintFunction {
IteratorCrementMemberOperator() {
this.hasName(["operator++", "operator--"]) and
this.getDeclaringType() instanceof Iterator
this.getClassAndName(["operator++", "operator--"]) instanceof Iterator
}

override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
Expand All @@ -220,10 +226,7 @@ private class IteratorCrementMemberOperator extends MemberFunction, DataFlowFunc
* A member `operator->` function for an iterator type.
*/
private class IteratorFieldMemberOperator extends Operator, TaintFunction {
IteratorFieldMemberOperator() {
this.hasName("operator->") and
this.getDeclaringType() instanceof Iterator
}
IteratorFieldMemberOperator() { this.getClassAndName("operator->") instanceof Iterator }

override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isQualifierObject() and
Expand All @@ -236,8 +239,7 @@ private class IteratorFieldMemberOperator extends Operator, TaintFunction {
*/
private class IteratorBinaryArithmeticMemberOperator extends MemberFunction, TaintFunction {
IteratorBinaryArithmeticMemberOperator() {
this.hasName(["operator+", "operator-"]) and
this.getDeclaringType() instanceof Iterator
this.getClassAndName(["operator+", "operator-"]) instanceof Iterator
}

override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
Expand All @@ -252,21 +254,24 @@ private class IteratorBinaryArithmeticMemberOperator extends MemberFunction, Tai
private class IteratorAssignArithmeticMemberOperator extends MemberFunction, DataFlowFunction,
TaintFunction {
IteratorAssignArithmeticMemberOperator() {
this.hasName(["operator+=", "operator-="]) and
this.getDeclaringType() instanceof Iterator
this.getClassAndName(["operator+=", "operator-="]) instanceof Iterator
}

override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
input.isQualifierAddress() and
output.isReturnValue()
or
input.isReturnValueDeref() and
output.isQualifierObject()
}

override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isQualifierObject() and
output.isReturnValueDeref()
or
// reverse flow from returned reference to the qualifier
input.isReturnValueDeref() and
output.isQualifierObject()
or
input.isParameterDeref(0) and
output.isQualifierObject()
}
}

Expand All @@ -275,10 +280,7 @@ private class IteratorAssignArithmeticMemberOperator extends MemberFunction, Dat
*/
private class IteratorArrayMemberOperator extends MemberFunction, TaintFunction,
IteratorReferenceFunction {
IteratorArrayMemberOperator() {
this.hasName("operator[]") and
this.getDeclaringType() instanceof Iterator
}
IteratorArrayMemberOperator() { this.getClassAndName("operator[]") instanceof Iterator }

override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isQualifierObject() and
Expand All @@ -295,8 +297,7 @@ private class IteratorArrayMemberOperator extends MemberFunction, TaintFunction,
*/
private class IteratorAssignmentMemberOperator extends MemberFunction, TaintFunction {
IteratorAssignmentMemberOperator() {
this.hasName("operator=") and
this.getDeclaringType() instanceof Iterator and
this.getClassAndName("operator=") instanceof Iterator and
not this instanceof CopyAssignmentOperator and
not this instanceof MoveAssignmentOperator
}
Expand Down Expand Up @@ -337,7 +338,7 @@ private class BeginOrEndFunction extends MemberFunction, TaintFunction, GetItera
*/
private class InserterIteratorFunction extends GetIteratorFunction {
InserterIteratorFunction() {
this.hasQualifiedName("std", ["front_inserter", "inserter", "back_inserter"])
this.hasQualifiedName(["std", "bsl"], ["front_inserter", "inserter", "back_inserter"])
}

override predicate getsIterator(FunctionInput input, FunctionOutput output) {
Expand Down
115 changes: 113 additions & 2 deletions cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected
Original file line number Diff line number Diff line change
Expand Up @@ -3197,6 +3197,56 @@
| standalone_iterators.cpp:90:8:90:8 | call to operator-- | standalone_iterators.cpp:90:5:90:5 | call to operator* | TAINT |
| standalone_iterators.cpp:90:8:90:8 | ref arg call to operator-- | standalone_iterators.cpp:90:6:90:7 | ref arg i2 | |
| standalone_iterators.cpp:90:13:90:13 | 0 | standalone_iterators.cpp:90:5:90:5 | ref arg call to operator* | TAINT |
| standalone_iterators.cpp:98:15:98:16 | call to container | standalone_iterators.cpp:101:6:101:7 | c1 | |
| standalone_iterators.cpp:98:15:98:16 | call to container | standalone_iterators.cpp:102:6:102:7 | c1 | |
| standalone_iterators.cpp:98:15:98:16 | call to container | standalone_iterators.cpp:106:6:106:7 | c1 | |
| standalone_iterators.cpp:98:15:98:16 | call to container | standalone_iterators.cpp:109:7:109:8 | c1 | |
| standalone_iterators.cpp:101:6:101:7 | c1 | standalone_iterators.cpp:101:9:101:13 | call to begin | TAINT |
| standalone_iterators.cpp:101:6:101:7 | ref arg c1 | standalone_iterators.cpp:102:6:102:7 | c1 | |
| standalone_iterators.cpp:101:6:101:7 | ref arg c1 | standalone_iterators.cpp:106:6:106:7 | c1 | |
| standalone_iterators.cpp:101:6:101:7 | ref arg c1 | standalone_iterators.cpp:109:7:109:8 | c1 | |
| standalone_iterators.cpp:101:9:101:13 | call to begin | standalone_iterators.cpp:101:2:101:15 | ... = ... | |
| standalone_iterators.cpp:101:9:101:13 | call to begin | standalone_iterators.cpp:103:3:103:3 | a | |
| standalone_iterators.cpp:101:9:101:13 | call to begin | standalone_iterators.cpp:104:7:104:7 | a | |
| standalone_iterators.cpp:102:6:102:7 | c1 | standalone_iterators.cpp:102:9:102:13 | call to begin | TAINT |
| standalone_iterators.cpp:102:6:102:7 | ref arg c1 | standalone_iterators.cpp:106:6:106:7 | c1 | |
| standalone_iterators.cpp:102:6:102:7 | ref arg c1 | standalone_iterators.cpp:109:7:109:8 | c1 | |
| standalone_iterators.cpp:102:9:102:13 | call to begin | standalone_iterators.cpp:102:2:102:15 | ... = ... | |
| standalone_iterators.cpp:102:9:102:13 | call to begin | standalone_iterators.cpp:107:7:107:7 | b | |
| standalone_iterators.cpp:103:2:103:2 | ref arg call to operator* | standalone_iterators.cpp:103:3:103:3 | ref arg a | TAINT |
| standalone_iterators.cpp:103:2:103:2 | ref arg call to operator* | standalone_iterators.cpp:106:6:106:7 | c1 | |
| standalone_iterators.cpp:103:2:103:2 | ref arg call to operator* | standalone_iterators.cpp:109:7:109:8 | c1 | |
| standalone_iterators.cpp:103:3:103:3 | a | standalone_iterators.cpp:103:2:103:2 | call to operator* | TAINT |
| standalone_iterators.cpp:103:3:103:3 | ref arg a | standalone_iterators.cpp:104:7:104:7 | a | |
| standalone_iterators.cpp:103:7:103:12 | call to source | standalone_iterators.cpp:103:2:103:2 | ref arg call to operator* | TAINT |
| standalone_iterators.cpp:104:7:104:7 | a [post update] | standalone_iterators.cpp:106:6:106:7 | c1 | |
| standalone_iterators.cpp:104:7:104:7 | a [post update] | standalone_iterators.cpp:109:7:109:8 | c1 | |
| standalone_iterators.cpp:106:6:106:7 | c1 | standalone_iterators.cpp:106:9:106:13 | call to begin | TAINT |
| standalone_iterators.cpp:106:6:106:7 | ref arg c1 | standalone_iterators.cpp:109:7:109:8 | c1 | |
| standalone_iterators.cpp:106:9:106:13 | call to begin | standalone_iterators.cpp:106:2:106:15 | ... = ... | |
| standalone_iterators.cpp:106:9:106:13 | call to begin | standalone_iterators.cpp:108:7:108:7 | c | |
| standalone_iterators.cpp:107:7:107:7 | b [post update] | standalone_iterators.cpp:109:7:109:8 | c1 | |
| standalone_iterators.cpp:108:7:108:7 | c [post update] | standalone_iterators.cpp:109:7:109:8 | c1 | |
| standalone_iterators.cpp:113:15:113:16 | call to container | standalone_iterators.cpp:116:7:116:8 | c1 | |
| standalone_iterators.cpp:113:15:113:16 | call to container | standalone_iterators.cpp:122:7:122:8 | c1 | |
| standalone_iterators.cpp:116:7:116:8 | c1 | standalone_iterators.cpp:116:10:116:14 | call to begin | TAINT |
| standalone_iterators.cpp:116:7:116:8 | ref arg c1 | standalone_iterators.cpp:122:7:122:8 | c1 | |
| standalone_iterators.cpp:116:10:116:14 | call to begin | standalone_iterators.cpp:116:2:116:16 | ... = ... | |
| standalone_iterators.cpp:116:10:116:14 | call to begin | standalone_iterators.cpp:117:7:117:8 | it | |
| standalone_iterators.cpp:116:10:116:14 | call to begin | standalone_iterators.cpp:118:2:118:3 | it | |
| standalone_iterators.cpp:116:10:116:14 | call to begin | standalone_iterators.cpp:119:7:119:8 | it | |
| standalone_iterators.cpp:116:10:116:14 | call to begin | standalone_iterators.cpp:120:2:120:3 | it | |
| standalone_iterators.cpp:116:10:116:14 | call to begin | standalone_iterators.cpp:121:7:121:8 | it | |
| standalone_iterators.cpp:117:7:117:8 | it [post update] | standalone_iterators.cpp:122:7:122:8 | c1 | |
| standalone_iterators.cpp:118:2:118:3 | it | standalone_iterators.cpp:118:5:118:5 | call to operator+= | |
| standalone_iterators.cpp:118:2:118:3 | ref arg it | standalone_iterators.cpp:119:7:119:8 | it | |
| standalone_iterators.cpp:118:2:118:3 | ref arg it | standalone_iterators.cpp:120:2:120:3 | it | |
| standalone_iterators.cpp:118:2:118:3 | ref arg it | standalone_iterators.cpp:121:7:121:8 | it | |
| standalone_iterators.cpp:118:2:118:3 | ref arg it | standalone_iterators.cpp:122:7:122:8 | c1 | |
| standalone_iterators.cpp:118:8:118:8 | 1 | standalone_iterators.cpp:118:2:118:3 | ref arg it | TAINT |
| standalone_iterators.cpp:120:2:120:3 | it | standalone_iterators.cpp:120:5:120:5 | call to operator+= | |
| standalone_iterators.cpp:120:2:120:3 | ref arg it | standalone_iterators.cpp:121:7:121:8 | it | |
| standalone_iterators.cpp:120:8:120:13 | call to source | standalone_iterators.cpp:120:2:120:3 | ref arg it | TAINT |
| stl.h:75:8:75:8 | Unknown literal | stl.h:75:8:75:8 | constructor init of field container | TAINT |
| stl.h:75:8:75:8 | Unknown literal | stl.h:75:8:75:8 | constructor init of field container | TAINT |
| stl.h:75:8:75:8 | this | stl.h:75:8:75:8 | constructor init of field container [pre-this] | |
Expand Down Expand Up @@ -3876,12 +3926,12 @@
| string.cpp:408:8:408:9 | i2 | string.cpp:409:10:409:11 | i7 | |
| string.cpp:409:10:409:11 | i7 | string.cpp:409:12:409:12 | call to operator+= | |
| string.cpp:409:12:409:12 | call to operator+= | string.cpp:409:8:409:8 | call to operator* | TAINT |
| string.cpp:409:14:409:14 | 1 | string.cpp:409:12:409:12 | call to operator+= | |
| string.cpp:409:14:409:14 | 1 | string.cpp:409:10:409:11 | ref arg i7 | TAINT |
| string.cpp:410:8:410:9 | i2 | string.cpp:410:3:410:9 | ... = ... | |
| string.cpp:410:8:410:9 | i2 | string.cpp:411:10:411:11 | i8 | |
| string.cpp:411:10:411:11 | i8 | string.cpp:411:12:411:12 | call to operator-= | |
| string.cpp:411:12:411:12 | call to operator-= | string.cpp:411:8:411:8 | call to operator* | TAINT |
| string.cpp:411:14:411:14 | 1 | string.cpp:411:12:411:12 | call to operator-= | |
| string.cpp:411:14:411:14 | 1 | string.cpp:411:10:411:11 | ref arg i8 | TAINT |
| string.cpp:413:8:413:9 | s2 | string.cpp:413:11:413:13 | call to end | TAINT |
| string.cpp:413:11:413:13 | call to end | string.cpp:413:3:413:15 | ... = ... | |
| string.cpp:413:11:413:13 | call to end | string.cpp:414:5:414:6 | i9 | |
Expand Down Expand Up @@ -7481,3 +7531,64 @@
| vector.cpp:496:25:496:30 | call to source | vector.cpp:496:2:496:3 | ref arg v2 | TAINT |
| vector.cpp:496:25:496:30 | call to source | vector.cpp:496:5:496:11 | call to emplace | TAINT |
| vector.cpp:497:7:497:8 | ref arg v2 | vector.cpp:498:1:498:1 | v2 | |
| vector.cpp:503:18:503:21 | {...} | vector.cpp:506:8:506:9 | as | |
| vector.cpp:503:18:503:21 | {...} | vector.cpp:507:8:507:9 | as | |
| vector.cpp:503:18:503:21 | {...} | vector.cpp:509:9:509:10 | as | |
| vector.cpp:503:18:503:21 | {...} | vector.cpp:515:8:515:9 | as | |
| vector.cpp:503:20:503:20 | 0 | vector.cpp:503:18:503:21 | {...} | TAINT |
| vector.cpp:506:8:506:9 | as | vector.cpp:506:8:506:12 | access to array | |
| vector.cpp:506:11:506:11 | 1 | vector.cpp:506:8:506:12 | access to array | TAINT |
| vector.cpp:507:8:507:9 | as | vector.cpp:507:8:507:19 | access to array | |
| vector.cpp:507:11:507:16 | call to source | vector.cpp:507:8:507:19 | access to array | TAINT |
| vector.cpp:509:9:509:10 | as | vector.cpp:509:3:509:10 | ... = ... | |
| vector.cpp:509:9:509:10 | as | vector.cpp:510:9:510:11 | ptr | |
| vector.cpp:509:9:509:10 | as | vector.cpp:511:3:511:5 | ptr | |
| vector.cpp:510:9:510:11 | ptr | vector.cpp:510:8:510:11 | * ... | TAINT |
| vector.cpp:511:3:511:5 | ptr | vector.cpp:511:3:511:10 | ... += ... | TAINT |
| vector.cpp:511:3:511:10 | ... += ... | vector.cpp:512:9:512:11 | ptr | |
| vector.cpp:511:3:511:10 | ... += ... | vector.cpp:513:3:513:5 | ptr | |
| vector.cpp:511:10:511:10 | 1 | vector.cpp:511:3:511:10 | ... += ... | TAINT |
| vector.cpp:512:9:512:11 | ptr | vector.cpp:512:8:512:11 | * ... | TAINT |
| vector.cpp:513:3:513:5 | ptr | vector.cpp:513:3:513:17 | ... += ... | TAINT |
| vector.cpp:513:3:513:17 | ... += ... | vector.cpp:514:9:514:11 | ptr | |
| vector.cpp:513:10:513:15 | call to source | vector.cpp:513:3:513:17 | ... += ... | TAINT |
| vector.cpp:514:9:514:11 | ptr | vector.cpp:514:8:514:11 | * ... | TAINT |
| vector.cpp:515:8:515:9 | as | vector.cpp:515:8:515:12 | access to array | |
| vector.cpp:515:11:515:11 | 1 | vector.cpp:515:8:515:12 | access to array | TAINT |
| vector.cpp:520:25:520:31 | call to vector | vector.cpp:523:8:523:9 | vs | |
| vector.cpp:520:25:520:31 | call to vector | vector.cpp:524:8:524:9 | vs | |
| vector.cpp:520:25:520:31 | call to vector | vector.cpp:526:8:526:9 | vs | |
| vector.cpp:520:25:520:31 | call to vector | vector.cpp:532:8:532:9 | vs | |
| vector.cpp:520:25:520:31 | call to vector | vector.cpp:533:2:533:2 | vs | |
| vector.cpp:520:30:520:30 | 0 | vector.cpp:520:25:520:31 | call to vector | TAINT |
| vector.cpp:523:8:523:9 | ref arg vs | vector.cpp:524:8:524:9 | vs | |
| vector.cpp:523:8:523:9 | ref arg vs | vector.cpp:526:8:526:9 | vs | |
| vector.cpp:523:8:523:9 | ref arg vs | vector.cpp:532:8:532:9 | vs | |
| vector.cpp:523:8:523:9 | ref arg vs | vector.cpp:533:2:533:2 | vs | |
| vector.cpp:523:8:523:9 | vs | vector.cpp:523:10:523:10 | call to operator[] | TAINT |
| vector.cpp:524:8:524:9 | ref arg vs | vector.cpp:526:8:526:9 | vs | |
| vector.cpp:524:8:524:9 | ref arg vs | vector.cpp:532:8:532:9 | vs | |
| vector.cpp:524:8:524:9 | ref arg vs | vector.cpp:533:2:533:2 | vs | |
| vector.cpp:524:8:524:9 | vs | vector.cpp:524:10:524:10 | call to operator[] | TAINT |
| vector.cpp:526:8:526:9 | ref arg vs | vector.cpp:532:8:532:9 | vs | |
| vector.cpp:526:8:526:9 | ref arg vs | vector.cpp:533:2:533:2 | vs | |
| vector.cpp:526:8:526:9 | vs | vector.cpp:526:11:526:15 | call to begin | TAINT |
| vector.cpp:526:11:526:15 | call to begin | vector.cpp:526:3:526:17 | ... = ... | |
| vector.cpp:526:11:526:15 | call to begin | vector.cpp:527:9:527:10 | it | |
| vector.cpp:526:11:526:15 | call to begin | vector.cpp:528:3:528:4 | it | |
| vector.cpp:526:11:526:15 | call to begin | vector.cpp:529:9:529:10 | it | |
| vector.cpp:526:11:526:15 | call to begin | vector.cpp:530:3:530:4 | it | |
| vector.cpp:526:11:526:15 | call to begin | vector.cpp:531:9:531:10 | it | |
| vector.cpp:527:9:527:10 | it | vector.cpp:527:8:527:8 | call to operator* | TAINT |
| vector.cpp:528:3:528:4 | it | vector.cpp:528:6:528:6 | call to operator+= | |
| vector.cpp:528:3:528:4 | ref arg it | vector.cpp:529:9:529:10 | it | |
| vector.cpp:528:3:528:4 | ref arg it | vector.cpp:530:3:530:4 | it | |
| vector.cpp:528:3:528:4 | ref arg it | vector.cpp:531:9:531:10 | it | |
| vector.cpp:528:9:528:9 | 1 | vector.cpp:528:3:528:4 | ref arg it | TAINT |
| vector.cpp:529:9:529:10 | it | vector.cpp:529:8:529:8 | call to operator* | TAINT |
| vector.cpp:530:3:530:4 | it | vector.cpp:530:6:530:6 | call to operator+= | |
| vector.cpp:530:3:530:4 | ref arg it | vector.cpp:531:9:531:10 | it | |
| vector.cpp:530:9:530:14 | call to source | vector.cpp:530:3:530:4 | ref arg it | TAINT |
| vector.cpp:531:9:531:10 | it | vector.cpp:531:8:531:8 | call to operator* | TAINT |
| vector.cpp:532:8:532:9 | ref arg vs | vector.cpp:533:2:533:2 | vs | |
| vector.cpp:532:8:532:9 | vs | vector.cpp:532:10:532:10 | call to operator[] | TAINT |
Loading