C++: Add set/map constructor models.

This commit is contained in:
Geoffrey White
2020-09-30 17:37:56 +01:00
parent 6520f9d0fb
commit cafd320953
7 changed files with 71 additions and 7 deletions

View File

@@ -5,6 +5,33 @@
import semmle.code.cpp.models.interfaces.Taint
import semmle.code.cpp.models.implementations.Iterator
/**
* Additional model for map constructors using iterator inputs.
*/
class StdMapConstructor extends Constructor, TaintFunction {
StdMapConstructor() {
this.hasQualifiedName("std", "map", "map") or
this.hasQualifiedName("std", "unordered_map", "unordered_map")
}
/**
* Gets the index of a parameter to this function that is an iterator.
*/
int getAnIteratorParameterIndex() {
getParameter(result).getUnspecifiedType() instanceof Iterator
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// taint flow from any parameter of an iterator type to the qualifier
input.isParameterDeref(getAnIteratorParameterIndex()) and
(
output.isReturnValue() // TODO: this is only needed for AST data flow, which treats constructors as returning the new object
or
output.isQualifierObject()
)
}
}
/**
* The standard map `insert` and `insert_or_assign` functions.
*/

View File

@@ -5,13 +5,38 @@
import semmle.code.cpp.models.interfaces.Taint
import semmle.code.cpp.models.implementations.Iterator
/**
* Additional model for set constructors using iterator inputs.
*/
class StdSetConstructor extends Constructor, TaintFunction {
StdSetConstructor() {
this.hasQualifiedName("std", "set", "set") or
this.hasQualifiedName("std", "unordered_set", "unordered_set")
}
/**
* Gets the index of a parameter to this function that is an iterator.
*/
int getAnIteratorParameterIndex() {
getParameter(result).getUnspecifiedType() instanceof Iterator
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// taint flow from any parameter of an iterator type to the qualifier
input.isParameterDeref(getAnIteratorParameterIndex()) and
(
output.isReturnValue() // TODO: this is only needed for AST data flow, which treats constructors as returning the new object
or
output.isQualifierObject()
)
}
}
/**
* The standard set `insert` and `insert_or_assign` functions.
*/
class StdSetInsert extends TaintFunction {
StdSetInsert() {
this.hasQualifiedName("std", ["set", "unordered_set"], "insert")
}
StdSetInsert() { this.hasQualifiedName("std", ["set", "unordered_set"], "insert") }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from last parameter to qualifier and return value

View File

@@ -2095,11 +2095,13 @@
| set.cpp:41:22:41:42 | call to set | set.cpp:46:7:46:8 | s9 | |
| set.cpp:41:22:41:42 | call to set | set.cpp:50:7:50:8 | s9 | |
| set.cpp:41:22:41:42 | call to set | set.cpp:126:1:126:1 | s9 | |
| set.cpp:41:25:41:29 | call to begin | set.cpp:41:22:41:42 | call to set | TAINT |
| set.cpp:41:34:41:35 | ref arg s2 | set.cpp:43:8:43:9 | s2 | |
| set.cpp:41:34:41:35 | ref arg s2 | set.cpp:59:12:59:13 | s2 | |
| set.cpp:41:34:41:35 | ref arg s2 | set.cpp:59:30:59:31 | s2 | |
| set.cpp:41:34:41:35 | ref arg s2 | set.cpp:126:1:126:1 | s2 | |
| set.cpp:41:34:41:35 | s2 | set.cpp:41:37:41:39 | call to end | TAINT |
| set.cpp:41:37:41:39 | call to end | set.cpp:41:22:41:42 | call to set | TAINT |
| set.cpp:42:19:42:21 | call to set | set.cpp:43:2:43:4 | s10 | |
| set.cpp:42:19:42:21 | call to set | set.cpp:47:7:47:9 | s10 | |
| set.cpp:42:19:42:21 | call to set | set.cpp:51:7:51:9 | s10 | |
@@ -2569,11 +2571,13 @@
| set.cpp:155:32:155:52 | call to unordered_set | set.cpp:160:7:160:8 | s9 | |
| set.cpp:155:32:155:52 | call to unordered_set | set.cpp:164:7:164:8 | s9 | |
| set.cpp:155:32:155:52 | call to unordered_set | set.cpp:238:1:238:1 | s9 | |
| set.cpp:155:35:155:39 | call to begin | set.cpp:155:32:155:52 | call to unordered_set | TAINT |
| set.cpp:155:44:155:45 | ref arg s2 | set.cpp:157:8:157:9 | s2 | |
| set.cpp:155:44:155:45 | ref arg s2 | set.cpp:173:12:173:13 | s2 | |
| set.cpp:155:44:155:45 | ref arg s2 | set.cpp:173:30:173:31 | s2 | |
| set.cpp:155:44:155:45 | ref arg s2 | set.cpp:238:1:238:1 | s2 | |
| set.cpp:155:44:155:45 | s2 | set.cpp:155:47:155:49 | call to end | TAINT |
| set.cpp:155:47:155:49 | call to end | set.cpp:155:32:155:52 | call to unordered_set | TAINT |
| set.cpp:156:29:156:31 | call to unordered_set | set.cpp:157:2:157:4 | s10 | |
| set.cpp:156:29:156:31 | call to unordered_set | set.cpp:161:7:161:9 | s10 | |
| set.cpp:156:29:156:31 | call to unordered_set | set.cpp:165:7:165:9 | s10 | |

View File

@@ -43,11 +43,11 @@ void test_set()
s10 = s2;
sink(s7); // tainted
sink(s8); // tainted
sink(s9); // tainted [NOT DETECTED]
sink(s9); // tainted
sink(s10); // tainted
sink(s7.find("abc")); // tainted
sink(s8.find("abc")); // tainted
sink(s9.find("abc")); // tainted [NOT DETECTED]
sink(s9.find("abc")); // tainted
sink(s10.find("abc")); // tainted
// iterators
@@ -157,11 +157,11 @@ void test_unordered_set()
s10 = s2;
sink(s7); // tainted
sink(s8); // tainted
sink(s9); // tainted [NOT DETECTED]
sink(s9); // tainted
sink(s10); // tainted
sink(s7.find("abc")); // tainted
sink(s8.find("abc")); // tainted
sink(s9.find("abc")); // tainted [NOT DETECTED]
sink(s9.find("abc")); // tainted
sink(s10.find("abc")); // tainted
// iterators

View File

@@ -198,9 +198,11 @@
| set.cpp:36:10:36:13 | call to find | set.cpp:20:17:20:22 | call to source |
| set.cpp:44:7:44:8 | call to set | set.cpp:20:17:20:22 | call to source |
| set.cpp:45:7:45:8 | call to set | set.cpp:20:17:20:22 | call to source |
| set.cpp:46:7:46:8 | call to set | set.cpp:20:17:20:22 | call to source |
| set.cpp:47:7:47:9 | call to set | set.cpp:20:17:20:22 | call to source |
| set.cpp:48:10:48:13 | call to find | set.cpp:20:17:20:22 | call to source |
| set.cpp:49:10:49:13 | call to find | set.cpp:20:17:20:22 | call to source |
| set.cpp:50:10:50:13 | call to find | set.cpp:20:17:20:22 | call to source |
| set.cpp:51:11:51:14 | call to find | set.cpp:20:17:20:22 | call to source |
| set.cpp:61:8:61:8 | call to operator* | set.cpp:20:17:20:22 | call to source |
| set.cpp:78:7:78:9 | call to set | set.cpp:76:13:76:18 | call to source |
@@ -230,9 +232,11 @@
| set.cpp:150:10:150:13 | call to find | set.cpp:134:17:134:22 | call to source |
| set.cpp:158:7:158:8 | call to unordered_set | set.cpp:134:17:134:22 | call to source |
| set.cpp:159:7:159:8 | call to unordered_set | set.cpp:134:17:134:22 | call to source |
| set.cpp:160:7:160:8 | call to unordered_set | set.cpp:134:17:134:22 | call to source |
| set.cpp:161:7:161:9 | call to unordered_set | set.cpp:134:17:134:22 | call to source |
| set.cpp:162:10:162:13 | call to find | set.cpp:134:17:134:22 | call to source |
| set.cpp:163:10:163:13 | call to find | set.cpp:134:17:134:22 | call to source |
| set.cpp:164:10:164:13 | call to find | set.cpp:134:17:134:22 | call to source |
| set.cpp:165:11:165:14 | call to find | set.cpp:134:17:134:22 | call to source |
| set.cpp:175:8:175:8 | call to operator* | set.cpp:134:17:134:22 | call to source |
| set.cpp:190:7:190:9 | call to unordered_set | set.cpp:188:13:188:18 | call to source |

View File

@@ -154,6 +154,7 @@
| set.cpp:30:7:30:8 | set.cpp:20:17:20:22 | AST only |
| set.cpp:44:7:44:8 | set.cpp:20:17:20:22 | AST only |
| set.cpp:45:7:45:8 | set.cpp:20:17:20:22 | AST only |
| set.cpp:46:7:46:8 | set.cpp:20:17:20:22 | AST only |
| set.cpp:47:7:47:9 | set.cpp:20:17:20:22 | AST only |
| set.cpp:48:10:48:13 | set.cpp:20:17:20:22 | AST only |
| set.cpp:49:10:49:13 | set.cpp:20:17:20:22 | AST only |
@@ -180,6 +181,7 @@
| set.cpp:144:7:144:8 | set.cpp:134:17:134:22 | AST only |
| set.cpp:158:7:158:8 | set.cpp:134:17:134:22 | AST only |
| set.cpp:159:7:159:8 | set.cpp:134:17:134:22 | AST only |
| set.cpp:160:7:160:8 | set.cpp:134:17:134:22 | AST only |
| set.cpp:161:7:161:9 | set.cpp:134:17:134:22 | AST only |
| set.cpp:162:10:162:13 | set.cpp:134:17:134:22 | AST only |
| set.cpp:163:10:163:13 | set.cpp:134:17:134:22 | AST only |

View File

@@ -138,6 +138,7 @@
| set.cpp:32:10:32:13 | call to find | set.cpp:20:17:20:22 | call to source |
| set.cpp:34:10:34:13 | call to find | set.cpp:22:29:22:34 | call to source |
| set.cpp:36:10:36:13 | call to find | set.cpp:20:17:20:22 | call to source |
| set.cpp:50:10:50:13 | call to find | set.cpp:20:17:20:22 | call to source |
| set.cpp:51:11:51:14 | call to find | set.cpp:20:17:20:22 | call to source |
| set.cpp:61:8:61:8 | call to operator* | set.cpp:20:17:20:22 | call to source |
| set.cpp:61:8:61:11 | (reference dereference) | set.cpp:20:17:20:22 | call to source |
@@ -148,6 +149,7 @@
| set.cpp:146:10:146:13 | call to find | set.cpp:134:17:134:22 | call to source |
| set.cpp:148:10:148:13 | call to find | set.cpp:136:29:136:34 | call to source |
| set.cpp:150:10:150:13 | call to find | set.cpp:134:17:134:22 | call to source |
| set.cpp:164:10:164:13 | call to find | set.cpp:134:17:134:22 | call to source |
| set.cpp:165:11:165:14 | call to find | set.cpp:134:17:134:22 | call to source |
| set.cpp:175:8:175:8 | call to operator* | set.cpp:134:17:134:22 | call to source |
| set.cpp:175:8:175:11 | (reference dereference) | set.cpp:134:17:134:22 | call to source |