diff --git a/cpp/ql/src/semmle/code/cpp/models/implementations/StdMap.qll b/cpp/ql/src/semmle/code/cpp/models/implementations/StdMap.qll index 71f3e7217d9..b85b6435ff5 100644 --- a/cpp/ql/src/semmle/code/cpp/models/implementations/StdMap.qll +++ b/cpp/ql/src/semmle/code/cpp/models/implementations/StdMap.qll @@ -56,3 +56,20 @@ class StdMapSwap extends TaintFunction { output.isQualifierObject() } } + +/** + * The standard map functions `at` and `operator[]`. + */ +class StdMapAt extends TaintFunction { + StdMapAt() { this.hasQualifiedName("std", ["map", "unordered_map"], ["at", "operator[]"]) } + + override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { + // flow from qualifier to referenced return value + input.isQualifierObject() and + output.isReturnValueDeref() + or + // reverse flow from returned reference to the qualifier + input.isReturnValueDeref() and + output.isQualifierObject() + } +} 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 814c80f4cae..7882c9c1106 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected @@ -852,25 +852,37 @@ | map.cpp:163:42:163:44 | call to map | map.cpp:167:7:167:9 | m13 | | | map.cpp:163:42:163:44 | call to map | map.cpp:171:7:171:9 | m13 | | | map.cpp:163:42:163:44 | call to map | map.cpp:249:1:249:1 | m13 | | +| map.cpp:164:7:164:9 | m10 | map.cpp:164:10:164:10 | call to operator[] | TAINT | | map.cpp:164:7:164:9 | ref arg m10 | map.cpp:168:7:168:9 | m10 | | | map.cpp:164:7:164:9 | ref arg m10 | map.cpp:249:1:249:1 | m10 | | | map.cpp:164:7:164:24 | ... = ... | map.cpp:164:10:164:10 | call to operator[] [post update] | | +| map.cpp:164:10:164:10 | call to operator[] [post update] | map.cpp:164:7:164:9 | ref arg m10 | TAINT | | map.cpp:164:20:164:24 | def | map.cpp:164:7:164:24 | ... = ... | | +| map.cpp:165:7:165:9 | m11 | map.cpp:165:10:165:10 | call to operator[] | TAINT | | map.cpp:165:7:165:9 | ref arg m11 | map.cpp:169:7:169:9 | m11 | | | map.cpp:165:7:165:9 | ref arg m11 | map.cpp:249:1:249:1 | m11 | | | map.cpp:165:7:165:27 | ... = ... | map.cpp:165:10:165:10 | call to operator[] [post update] | | +| map.cpp:165:10:165:10 | call to operator[] [post update] | map.cpp:165:7:165:9 | ref arg m11 | TAINT | | map.cpp:165:20:165:25 | call to source | map.cpp:165:7:165:27 | ... = ... | | +| map.cpp:166:7:166:9 | m12 | map.cpp:166:11:166:12 | call to at | TAINT | | map.cpp:166:7:166:9 | ref arg m12 | map.cpp:170:7:170:9 | m12 | | | map.cpp:166:7:166:9 | ref arg m12 | map.cpp:249:1:249:1 | m12 | | | map.cpp:166:7:166:27 | ... = ... | map.cpp:166:11:166:12 | call to at [post update] | | +| map.cpp:166:11:166:12 | call to at [post update] | map.cpp:166:7:166:9 | ref arg m12 | TAINT | | map.cpp:166:23:166:27 | def | map.cpp:166:7:166:27 | ... = ... | | +| map.cpp:167:7:167:9 | m13 | map.cpp:167:11:167:12 | call to at | TAINT | | map.cpp:167:7:167:9 | ref arg m13 | map.cpp:171:7:171:9 | m13 | | | map.cpp:167:7:167:9 | ref arg m13 | map.cpp:249:1:249:1 | m13 | | | map.cpp:167:7:167:30 | ... = ... | map.cpp:167:11:167:12 | call to at [post update] | | +| map.cpp:167:11:167:12 | call to at [post update] | map.cpp:167:7:167:9 | ref arg m13 | TAINT | | map.cpp:167:23:167:28 | call to source | map.cpp:167:7:167:30 | ... = ... | | +| map.cpp:168:7:168:9 | m10 | map.cpp:168:10:168:10 | call to operator[] | TAINT | | map.cpp:168:7:168:9 | ref arg m10 | map.cpp:249:1:249:1 | m10 | | +| map.cpp:169:7:169:9 | m11 | map.cpp:169:10:169:10 | call to operator[] | TAINT | | map.cpp:169:7:169:9 | ref arg m11 | map.cpp:249:1:249:1 | m11 | | +| map.cpp:170:7:170:9 | m12 | map.cpp:170:10:170:10 | call to operator[] | TAINT | | map.cpp:170:7:170:9 | ref arg m12 | map.cpp:249:1:249:1 | m12 | | +| map.cpp:171:7:171:9 | m13 | map.cpp:171:10:171:10 | call to operator[] | TAINT | | map.cpp:171:7:171:9 | ref arg m13 | map.cpp:249:1:249:1 | m13 | | | map.cpp:174:27:174:29 | call to map | map.cpp:175:2:175:4 | m14 | | | map.cpp:174:27:174:29 | call to map | map.cpp:176:2:176:4 | m14 | | @@ -1467,25 +1479,37 @@ | map.cpp:315:52:315:54 | call to unordered_map | map.cpp:319:7:319:9 | m13 | | | map.cpp:315:52:315:54 | call to unordered_map | map.cpp:323:7:323:9 | m13 | | | map.cpp:315:52:315:54 | call to unordered_map | map.cpp:398:1:398:1 | m13 | | +| map.cpp:316:7:316:9 | m10 | map.cpp:316:10:316:10 | call to operator[] | TAINT | | map.cpp:316:7:316:9 | ref arg m10 | map.cpp:320:7:320:9 | m10 | | | map.cpp:316:7:316:9 | ref arg m10 | map.cpp:398:1:398:1 | m10 | | | map.cpp:316:7:316:24 | ... = ... | map.cpp:316:10:316:10 | call to operator[] [post update] | | +| map.cpp:316:10:316:10 | call to operator[] [post update] | map.cpp:316:7:316:9 | ref arg m10 | TAINT | | map.cpp:316:20:316:24 | def | map.cpp:316:7:316:24 | ... = ... | | +| map.cpp:317:7:317:9 | m11 | map.cpp:317:10:317:10 | call to operator[] | TAINT | | map.cpp:317:7:317:9 | ref arg m11 | map.cpp:321:7:321:9 | m11 | | | map.cpp:317:7:317:9 | ref arg m11 | map.cpp:398:1:398:1 | m11 | | | map.cpp:317:7:317:27 | ... = ... | map.cpp:317:10:317:10 | call to operator[] [post update] | | +| map.cpp:317:10:317:10 | call to operator[] [post update] | map.cpp:317:7:317:9 | ref arg m11 | TAINT | | map.cpp:317:20:317:25 | call to source | map.cpp:317:7:317:27 | ... = ... | | +| map.cpp:318:7:318:9 | m12 | map.cpp:318:11:318:12 | call to at | TAINT | | map.cpp:318:7:318:9 | ref arg m12 | map.cpp:322:7:322:9 | m12 | | | map.cpp:318:7:318:9 | ref arg m12 | map.cpp:398:1:398:1 | m12 | | | map.cpp:318:7:318:27 | ... = ... | map.cpp:318:11:318:12 | call to at [post update] | | +| map.cpp:318:11:318:12 | call to at [post update] | map.cpp:318:7:318:9 | ref arg m12 | TAINT | | map.cpp:318:23:318:27 | def | map.cpp:318:7:318:27 | ... = ... | | +| map.cpp:319:7:319:9 | m13 | map.cpp:319:11:319:12 | call to at | TAINT | | map.cpp:319:7:319:9 | ref arg m13 | map.cpp:323:7:323:9 | m13 | | | map.cpp:319:7:319:9 | ref arg m13 | map.cpp:398:1:398:1 | m13 | | | map.cpp:319:7:319:30 | ... = ... | map.cpp:319:11:319:12 | call to at [post update] | | +| map.cpp:319:11:319:12 | call to at [post update] | map.cpp:319:7:319:9 | ref arg m13 | TAINT | | map.cpp:319:23:319:28 | call to source | map.cpp:319:7:319:30 | ... = ... | | +| map.cpp:320:7:320:9 | m10 | map.cpp:320:10:320:10 | call to operator[] | TAINT | | map.cpp:320:7:320:9 | ref arg m10 | map.cpp:398:1:398:1 | m10 | | +| map.cpp:321:7:321:9 | m11 | map.cpp:321:10:321:10 | call to operator[] | TAINT | | map.cpp:321:7:321:9 | ref arg m11 | map.cpp:398:1:398:1 | m11 | | +| map.cpp:322:7:322:9 | m12 | map.cpp:322:10:322:10 | call to operator[] | TAINT | | map.cpp:322:7:322:9 | ref arg m12 | map.cpp:398:1:398:1 | m12 | | +| map.cpp:323:7:323:9 | m13 | map.cpp:323:10:323:10 | call to operator[] | TAINT | | map.cpp:323:7:323:9 | ref arg m13 | map.cpp:398:1:398:1 | m13 | | | map.cpp:326:37:326:39 | call to unordered_map | map.cpp:327:2:327:4 | m14 | | | map.cpp:326:37:326:39 | call to unordered_map | map.cpp:328:2:328:4 | m14 | | diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/map.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/map.cpp index d878fd4d37e..34441b012ae 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/map.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/map.cpp @@ -166,9 +166,9 @@ void test_map() sink(m12.at("abc") = "def"); sink(m13.at("abc") = source()); // tainted sink(m10["abc"]); - sink(m11["abc"]); // tainted [NOT DETECTED] + sink(m11["abc"]); // tainted sink(m12["abc"]); - sink(m13["abc"]); // tainted [NOT DETECTED] + sink(m13["abc"]); // tainted // ranges std::map m14; @@ -318,9 +318,9 @@ void test_unordered_map() sink(m12.at("abc") = "def"); sink(m13.at("abc") = source()); // tainted sink(m10["abc"]); - sink(m11["abc"]); // tainted [NOT DETECTED] + sink(m11["abc"]); // tainted sink(m12["abc"]); - sink(m13["abc"]); // tainted [NOT DETECTED] + sink(m13["abc"]); // tainted // ranges std::unordered_map m14; 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 05d1a76d53a..f5b483010a8 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected @@ -57,6 +57,8 @@ | map.cpp:157:8:157:10 | call to pair | map.cpp:106:32:106:37 | call to source | | map.cpp:165:7:165:27 | ... = ... | map.cpp:165:20:165:25 | call to source | | map.cpp:167:7:167:30 | ... = ... | map.cpp:167:23:167:28 | call to source | +| map.cpp:169:10:169:10 | call to operator[] | map.cpp:165:20:165:25 | call to source | +| map.cpp:171:10:171:10 | call to operator[] | map.cpp:167:23:167:28 | call to source | | map.cpp:190:7:190:9 | call to map | map.cpp:188:39:188:44 | call to source | | map.cpp:190:7:190:9 | call to map | map.cpp:188:49:188:54 | call to source | | map.cpp:193:7:193:9 | call to map | map.cpp:189:39:189:44 | call to source | @@ -100,6 +102,8 @@ | map.cpp:309:8:309:10 | call to pair | map.cpp:258:32:258:37 | call to source | | map.cpp:317:7:317:27 | ... = ... | map.cpp:317:20:317:25 | call to source | | map.cpp:319:7:319:30 | ... = ... | map.cpp:319:23:319:28 | call to source | +| map.cpp:321:10:321:10 | call to operator[] | map.cpp:317:20:317:25 | call to source | +| map.cpp:323:10:323:10 | call to operator[] | map.cpp:319:23:319:28 | call to source | | map.cpp:339:7:339:9 | call to unordered_map | map.cpp:337:39:337:44 | call to source | | map.cpp:339:7:339:9 | call to unordered_map | map.cpp:337:49:337:54 | call to source | | map.cpp:342:7:342:9 | call to unordered_map | map.cpp:338:39:338:44 | 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 9a4e5ec0f7a..3f0e87fac6b 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 @@ -54,6 +54,8 @@ | map.cpp:153:12:153:17 | map.cpp:105:39:105:44 | IR only | | map.cpp:158:12:158:16 | map.cpp:105:39:105:44 | IR only | | map.cpp:159:12:159:17 | map.cpp:105:39:105:44 | IR only | +| map.cpp:169:10:169:10 | map.cpp:165:20:165:25 | AST only | +| map.cpp:171:10:171:10 | map.cpp:167:23:167:28 | AST only | | map.cpp:190:7:190:9 | map.cpp:188:39:188:44 | AST only | | map.cpp:190:7:190:9 | map.cpp:188:49:188:54 | AST only | | map.cpp:193:7:193:9 | map.cpp:189:39:189:44 | AST only | @@ -98,6 +100,8 @@ | map.cpp:305:12:305:17 | map.cpp:257:39:257:44 | IR only | | map.cpp:310:12:310:16 | map.cpp:257:39:257:44 | IR only | | map.cpp:311:12:311:17 | map.cpp:257:39:257:44 | IR only | +| map.cpp:321:10:321:10 | map.cpp:317:20:317:25 | AST only | +| map.cpp:323:10:323:10 | map.cpp:319:23:319:28 | AST only | | map.cpp:339:7:339:9 | map.cpp:337:39:337:44 | AST only | | map.cpp:339:7:339:9 | map.cpp:337:49:337:54 | AST only | | map.cpp:342:7:342:9 | map.cpp:338:39:338:44 | AST only |