C++: Flow through operator>>.

This commit is contained in:
Geoffrey White
2020-09-11 13:41:36 +01:00
parent 5079deb92a
commit 56390c1aef
6 changed files with 123 additions and 12 deletions

View File

@@ -288,6 +288,63 @@ class StdStringAt extends TaintFunction {
}
}
/**
* The `std::basic_istream` template class.
*/
class StdBasicIStream extends TemplateClass {
StdBasicIStream() { this.hasQualifiedName("std", "basic_istream") }
}
/**
* The `std::istream` function `operator>>` (defined as a member function).
*/
class StdIStreamIn extends DataFlowFunction, TaintFunction {
StdIStreamIn() { this.hasQualifiedName("std", "basic_istream", "operator>>") }
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
// flow from qualifier to return value
input.isQualifierObject() and
output.isReturnValue()
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from qualifier to first parameter
input.isQualifierObject() and
output.isParameterDeref(0)
or
// reverse flow from returned reference to the qualifier
input.isReturnValueDeref() and
output.isQualifierObject()
}
}
/**
* The `std::istream` function `operator>>` (defined as a non-member function).
*/
class StdIStreamInNonMember extends DataFlowFunction, TaintFunction {
StdIStreamInNonMember() {
this.hasQualifiedName("std", "operator>>") and
this.getUnspecifiedType().(ReferenceType).getBaseType() =
any(StdBasicIStream s).getAnInstantiation()
}
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
// flow from first parameter to return value
input.isParameter(0) and
output.isReturnValue()
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
// flow from first parameter to second parameter
input.isParameterDeref(0) and
output.isParameterDeref(1)
or
// reverse flow from returned reference to the first parameter
input.isReturnValueDeref() and
output.isParameterDeref(0)
}
}
/**
* The `std::basic_ostream` template class.
*/

View File

@@ -1568,9 +1568,13 @@
| stringstream.cpp:76:14:76:19 | source | stringstream.cpp:76:11:76:11 | call to operator<< | TAINT |
| stringstream.cpp:77:7:77:9 | ref arg ss1 | stringstream.cpp:80:7:80:9 | ss1 | |
| stringstream.cpp:77:7:77:9 | ref arg ss1 | stringstream.cpp:82:7:82:9 | ss1 | |
| stringstream.cpp:77:7:77:9 | ss1 | stringstream.cpp:77:11:77:11 | call to operator>> | |
| stringstream.cpp:77:7:77:9 | ss1 | stringstream.cpp:77:14:77:15 | ref arg v1 | TAINT |
| stringstream.cpp:77:14:77:15 | ref arg v1 | stringstream.cpp:84:7:84:8 | v1 | |
| stringstream.cpp:78:7:78:9 | ref arg ss2 | stringstream.cpp:81:7:81:9 | ss2 | |
| stringstream.cpp:78:7:78:9 | ref arg ss2 | stringstream.cpp:83:7:83:9 | ss2 | |
| stringstream.cpp:78:7:78:9 | ss2 | stringstream.cpp:78:11:78:11 | call to operator>> | |
| stringstream.cpp:78:7:78:9 | ss2 | stringstream.cpp:78:14:78:15 | ref arg v2 | TAINT |
| stringstream.cpp:78:14:78:15 | ref arg v2 | stringstream.cpp:85:7:85:8 | v2 | |
| stringstream.cpp:82:7:82:9 | ss1 | stringstream.cpp:82:11:82:13 | call to str | TAINT |
| stringstream.cpp:83:7:83:9 | ss2 | stringstream.cpp:83:11:83:13 | call to str | TAINT |
@@ -1715,6 +1719,8 @@
| stringstream.cpp:145:7:145:9 | ref arg ss1 | stringstream.cpp:174:12:174:14 | ss1 | |
| stringstream.cpp:145:7:145:9 | ref arg ss1 | stringstream.cpp:176:12:176:14 | ss1 | |
| stringstream.cpp:145:7:145:9 | ref arg ss1 | stringstream.cpp:178:7:178:9 | ss1 | |
| stringstream.cpp:145:7:145:9 | ss1 | stringstream.cpp:145:11:145:11 | call to operator>> | |
| stringstream.cpp:145:7:145:9 | ss1 | stringstream.cpp:145:14:145:15 | ref arg s1 | TAINT |
| stringstream.cpp:145:14:145:15 | ref arg s1 | stringstream.cpp:148:7:148:8 | s1 | |
| stringstream.cpp:146:7:146:9 | ref arg ss2 | stringstream.cpp:147:7:147:9 | ss2 | |
| stringstream.cpp:146:7:146:9 | ref arg ss2 | stringstream.cpp:154:7:154:9 | ss2 | |
@@ -1725,6 +1731,8 @@
| stringstream.cpp:146:7:146:9 | ref arg ss2 | stringstream.cpp:175:12:175:14 | ss2 | |
| stringstream.cpp:146:7:146:9 | ref arg ss2 | stringstream.cpp:177:12:177:14 | ss2 | |
| stringstream.cpp:146:7:146:9 | ref arg ss2 | stringstream.cpp:179:7:179:9 | ss2 | |
| stringstream.cpp:146:7:146:9 | ss2 | stringstream.cpp:146:11:146:11 | call to operator>> | |
| stringstream.cpp:146:7:146:9 | ss2 | stringstream.cpp:146:14:146:15 | ref arg s2 | TAINT |
| stringstream.cpp:146:14:146:15 | ref arg s2 | stringstream.cpp:149:7:149:8 | s2 | |
| stringstream.cpp:147:7:147:9 | ref arg ss2 | stringstream.cpp:154:7:154:9 | ss2 | |
| stringstream.cpp:147:7:147:9 | ref arg ss2 | stringstream.cpp:155:7:155:9 | ss2 | |
@@ -1734,6 +1742,11 @@
| stringstream.cpp:147:7:147:9 | ref arg ss2 | stringstream.cpp:175:12:175:14 | ss2 | |
| stringstream.cpp:147:7:147:9 | ref arg ss2 | stringstream.cpp:177:12:177:14 | ss2 | |
| stringstream.cpp:147:7:147:9 | ref arg ss2 | stringstream.cpp:179:7:179:9 | ss2 | |
| stringstream.cpp:147:7:147:9 | ss2 | stringstream.cpp:147:11:147:11 | call to operator>> | |
| stringstream.cpp:147:7:147:9 | ss2 | stringstream.cpp:147:14:147:15 | ref arg s3 | TAINT |
| stringstream.cpp:147:11:147:11 | call to operator>> | stringstream.cpp:147:17:147:17 | call to operator>> | |
| stringstream.cpp:147:11:147:11 | call to operator>> | stringstream.cpp:147:20:147:21 | ref arg s4 | TAINT |
| stringstream.cpp:147:11:147:11 | ref arg call to operator>> | stringstream.cpp:147:7:147:9 | ref arg ss2 | TAINT |
| stringstream.cpp:147:14:147:15 | ref arg s3 | stringstream.cpp:150:7:150:8 | s3 | |
| stringstream.cpp:147:20:147:21 | ref arg s4 | stringstream.cpp:151:7:151:8 | s4 | |
| stringstream.cpp:153:7:153:9 | ref arg ss1 | stringstream.cpp:161:7:161:9 | ss1 | |
@@ -1742,6 +1755,8 @@
| stringstream.cpp:153:7:153:9 | ref arg ss1 | stringstream.cpp:174:12:174:14 | ss1 | |
| stringstream.cpp:153:7:153:9 | ref arg ss1 | stringstream.cpp:176:12:176:14 | ss1 | |
| stringstream.cpp:153:7:153:9 | ref arg ss1 | stringstream.cpp:178:7:178:9 | ss1 | |
| stringstream.cpp:153:7:153:9 | ss1 | stringstream.cpp:153:11:153:11 | call to operator>> | |
| stringstream.cpp:153:7:153:9 | ss1 | stringstream.cpp:153:14:153:15 | ref arg b1 | TAINT |
| stringstream.cpp:153:14:153:15 | ref arg b1 | stringstream.cpp:156:7:156:8 | b1 | |
| stringstream.cpp:154:7:154:9 | ref arg ss2 | stringstream.cpp:155:7:155:9 | ss2 | |
| stringstream.cpp:154:7:154:9 | ref arg ss2 | stringstream.cpp:162:7:162:9 | ss2 | |
@@ -1750,6 +1765,8 @@
| stringstream.cpp:154:7:154:9 | ref arg ss2 | stringstream.cpp:175:12:175:14 | ss2 | |
| stringstream.cpp:154:7:154:9 | ref arg ss2 | stringstream.cpp:177:12:177:14 | ss2 | |
| stringstream.cpp:154:7:154:9 | ref arg ss2 | stringstream.cpp:179:7:179:9 | ss2 | |
| stringstream.cpp:154:7:154:9 | ss2 | stringstream.cpp:154:11:154:11 | call to operator>> | |
| stringstream.cpp:154:7:154:9 | ss2 | stringstream.cpp:154:14:154:15 | ref arg b2 | TAINT |
| stringstream.cpp:154:14:154:15 | ref arg b2 | stringstream.cpp:157:7:157:8 | b2 | |
| stringstream.cpp:155:7:155:9 | ref arg ss2 | stringstream.cpp:162:7:162:9 | ss2 | |
| stringstream.cpp:155:7:155:9 | ref arg ss2 | stringstream.cpp:164:7:164:9 | ss2 | |
@@ -1757,6 +1774,11 @@
| stringstream.cpp:155:7:155:9 | ref arg ss2 | stringstream.cpp:175:12:175:14 | ss2 | |
| stringstream.cpp:155:7:155:9 | ref arg ss2 | stringstream.cpp:177:12:177:14 | ss2 | |
| stringstream.cpp:155:7:155:9 | ref arg ss2 | stringstream.cpp:179:7:179:9 | ss2 | |
| stringstream.cpp:155:7:155:9 | ss2 | stringstream.cpp:155:11:155:11 | call to operator>> | |
| stringstream.cpp:155:7:155:9 | ss2 | stringstream.cpp:155:14:155:15 | ref arg b3 | TAINT |
| stringstream.cpp:155:11:155:11 | call to operator>> | stringstream.cpp:155:17:155:17 | call to operator>> | |
| stringstream.cpp:155:11:155:11 | call to operator>> | stringstream.cpp:155:20:155:21 | ref arg b4 | TAINT |
| stringstream.cpp:155:11:155:11 | ref arg call to operator>> | stringstream.cpp:155:7:155:9 | ref arg ss2 | TAINT |
| stringstream.cpp:155:14:155:15 | ref arg b3 | stringstream.cpp:158:7:158:8 | b3 | |
| stringstream.cpp:155:20:155:21 | ref arg b4 | stringstream.cpp:159:7:159:8 | b4 | |
| stringstream.cpp:156:7:156:8 | b1 | stringstream.cpp:156:7:156:8 | call to basic_string | TAINT |

View File

@@ -75,14 +75,14 @@ void test_stringstream_int(int source)
sink(ss1 << 1234);
sink(ss2 << source); // tainted
sink(ss1 >> v1);
sink(ss2 >> v2); // tainted [NOT DETECTED]
sink(ss2 >> v2); // tainted
sink(ss1);
sink(ss2); // tainted
sink(ss1.str());
sink(ss2.str()); // tainted
sink(v1);
sink(v2); // tainted [NOT DETECTED]
sink(v2); // tainted
}
void test_stringstream_constructors()
@@ -143,20 +143,20 @@ void test_stringstream_in()
sink(ss2 << source()); // tainted
sink(ss1 >> s1);
sink(ss2 >> s2); // tainted [NOT DETECTED]
sink(ss2 >> s3 >> s4); // tainted [NOT DETECTED]
sink(ss2 >> s2); // tainted
sink(ss2 >> s3 >> s4); // tainted
sink(s1);
sink(s2); // tainted [NOT DETECTED]
sink(s3); // tainted [NOT DETECTED]
sink(s4); // tainted [NOT DETECTED]
sink(s2); // tainted
sink(s3); // tainted
sink(s4); // tainted
sink(ss1 >> b1);
sink(ss2 >> b2);
sink(ss2 >> b3 >> b4);
sink(ss2 >> b2); // tainted
sink(ss2 >> b3 >> b4); // tainted
sink(b1);
sink(b2); // tainted [NOT DETECTED]
sink(b3); // tainted [NOT DETECTED]
sink(b4); // tainted [NOT DETECTED]
sink(b2); // tainted
sink(b3); // tainted
sink(b4); // tainted
sink(ss1.read(b5, 100));
sink(ss2.read(b6, 100)); // tainted [NOT DETECTED]

View File

@@ -188,8 +188,10 @@
| stringstream.cpp:66:7:66:10 | ss12 | stringstream.cpp:63:18:63:23 | call to source |
| stringstream.cpp:67:7:67:10 | ss13 | stringstream.cpp:64:36:64:41 | call to source |
| stringstream.cpp:76:11:76:11 | call to operator<< | stringstream.cpp:70:32:70:37 | source |
| stringstream.cpp:78:11:78:11 | call to operator>> | stringstream.cpp:70:32:70:37 | source |
| stringstream.cpp:81:7:81:9 | ss2 | stringstream.cpp:70:32:70:37 | source |
| stringstream.cpp:83:11:83:13 | call to str | stringstream.cpp:70:32:70:37 | source |
| stringstream.cpp:85:7:85:8 | v2 | stringstream.cpp:70:32:70:37 | source |
| stringstream.cpp:100:11:100:11 | call to operator= | stringstream.cpp:100:31:100:36 | call to source |
| stringstream.cpp:103:7:103:9 | ss2 | stringstream.cpp:91:19:91:24 | call to source |
| stringstream.cpp:105:7:105:9 | ss4 | stringstream.cpp:95:44:95:49 | call to source |
@@ -197,6 +199,16 @@
| stringstream.cpp:121:7:121:9 | ss2 | stringstream.cpp:113:24:113:29 | call to source |
| stringstream.cpp:123:7:123:9 | ss4 | stringstream.cpp:115:24:115:29 | call to source |
| stringstream.cpp:143:11:143:11 | call to operator<< | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:146:11:146:11 | call to operator>> | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:147:17:147:17 | call to operator>> | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:149:7:149:8 | s2 | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:150:7:150:8 | s3 | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:151:7:151:8 | s4 | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:154:11:154:11 | call to operator>> | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:155:17:155:17 | call to operator>> | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:157:7:157:8 | call to basic_string | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:158:7:158:8 | call to basic_string | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:159:7:159:8 | call to basic_string | stringstream.cpp:143:14:143:19 | call to source |
| structlikeclass.cpp:35:8:35:9 | s1 | structlikeclass.cpp:29:22:29:27 | call to source |
| structlikeclass.cpp:36:8:36:9 | s2 | structlikeclass.cpp:30:24:30:29 | call to source |
| structlikeclass.cpp:37:8:37:9 | s3 | structlikeclass.cpp:29:22:29:27 | call to source |

View File

@@ -188,8 +188,10 @@
| stringstream.cpp:66:7:66:10 | stringstream.cpp:63:18:63:23 | AST only |
| stringstream.cpp:67:7:67:10 | stringstream.cpp:64:36:64:41 | AST only |
| stringstream.cpp:76:11:76:11 | stringstream.cpp:70:32:70:37 | AST only |
| stringstream.cpp:78:11:78:11 | stringstream.cpp:70:32:70:37 | AST only |
| stringstream.cpp:81:7:81:9 | stringstream.cpp:70:32:70:37 | AST only |
| stringstream.cpp:83:11:83:13 | stringstream.cpp:70:32:70:37 | AST only |
| stringstream.cpp:85:7:85:8 | stringstream.cpp:70:32:70:37 | AST only |
| stringstream.cpp:100:11:100:11 | stringstream.cpp:100:31:100:36 | AST only |
| stringstream.cpp:103:7:103:9 | stringstream.cpp:91:19:91:24 | AST only |
| stringstream.cpp:105:7:105:9 | stringstream.cpp:95:44:95:49 | AST only |
@@ -199,6 +201,16 @@
| stringstream.cpp:143:11:143:11 | stringstream.cpp:143:14:143:21 | IR only |
| stringstream.cpp:143:11:143:22 | stringstream.cpp:143:14:143:19 | IR only |
| stringstream.cpp:143:11:143:22 | stringstream.cpp:143:14:143:21 | IR only |
| stringstream.cpp:146:11:146:11 | stringstream.cpp:143:14:143:19 | AST only |
| stringstream.cpp:147:17:147:17 | stringstream.cpp:143:14:143:19 | AST only |
| stringstream.cpp:149:7:149:8 | stringstream.cpp:143:14:143:19 | AST only |
| stringstream.cpp:150:7:150:8 | stringstream.cpp:143:14:143:19 | AST only |
| stringstream.cpp:151:7:151:8 | stringstream.cpp:143:14:143:19 | AST only |
| stringstream.cpp:154:11:154:11 | stringstream.cpp:143:14:143:19 | AST only |
| stringstream.cpp:155:17:155:17 | stringstream.cpp:143:14:143:19 | AST only |
| stringstream.cpp:157:7:157:8 | stringstream.cpp:143:14:143:21 | IR only |
| stringstream.cpp:158:7:158:8 | stringstream.cpp:143:14:143:21 | IR only |
| stringstream.cpp:159:7:159:8 | stringstream.cpp:143:14:143:19 | AST only |
| swap1.cpp:78:12:78:16 | swap1.cpp:69:23:69:23 | AST only |
| swap1.cpp:87:13:87:17 | swap1.cpp:82:16:82:21 | AST only |
| swap1.cpp:88:13:88:17 | swap1.cpp:81:27:81:28 | AST only |

View File

@@ -70,6 +70,14 @@
| stringstream.cpp:143:11:143:22 | (reference dereference) | stringstream.cpp:143:14:143:21 | (const char *)... |
| stringstream.cpp:143:11:143:22 | (reference to) | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:143:11:143:22 | (reference to) | stringstream.cpp:143:14:143:21 | (const char *)... |
| stringstream.cpp:157:7:157:8 | (reference to) | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:157:7:157:8 | (reference to) | stringstream.cpp:143:14:143:21 | (const char *)... |
| stringstream.cpp:157:7:157:8 | call to basic_string | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:157:7:157:8 | call to basic_string | stringstream.cpp:143:14:143:21 | (const char *)... |
| stringstream.cpp:158:7:158:8 | (reference to) | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:158:7:158:8 | (reference to) | stringstream.cpp:143:14:143:21 | (const char *)... |
| stringstream.cpp:158:7:158:8 | call to basic_string | stringstream.cpp:143:14:143:19 | call to source |
| stringstream.cpp:158:7:158:8 | call to basic_string | stringstream.cpp:143:14:143:21 | (const char *)... |
| structlikeclass.cpp:35:8:35:9 | s1 | structlikeclass.cpp:29:22:29:27 | call to source |
| structlikeclass.cpp:36:8:36:9 | s2 | structlikeclass.cpp:30:24:30:29 | call to source |
| structlikeclass.cpp:37:8:37:9 | s3 | structlikeclass.cpp:29:22:29:27 | call to source |