diff --git a/cpp/ql/src/semmle/code/cpp/models/Models.qll b/cpp/ql/src/semmle/code/cpp/models/Models.qll index 71526b8fca2..0747b00c48d 100644 --- a/cpp/ql/src/semmle/code/cpp/models/Models.qll +++ b/cpp/ql/src/semmle/code/cpp/models/Models.qll @@ -6,3 +6,4 @@ private import implementations.Pure private import implementations.Strcat private import implementations.Strcpy private import implementations.Strftime +private import implementations.Swap diff --git a/cpp/ql/src/semmle/code/cpp/models/implementations/Swap.qll b/cpp/ql/src/semmle/code/cpp/models/implementations/Swap.qll new file mode 100644 index 00000000000..ec8f963fdbf --- /dev/null +++ b/cpp/ql/src/semmle/code/cpp/models/implementations/Swap.qll @@ -0,0 +1,23 @@ +import semmle.code.cpp.models.interfaces.DataFlow +import semmle.code.cpp.models.interfaces.Taint + +/** + * The standard function `swap`. + */ +class Swap extends DataFlowFunction { + Swap() { + this.hasQualifiedName("std", "swap") + } + + override predicate hasDataFlow(FunctionInput input, FunctionOutput output) { + ( + input.isInParameterPointer(0) and + output.isOutParameterPointer(1) + ) + or + ( + input.isInParameterPointer(1) and + output.isOutParameterPointer(0) + ) + } +} 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 b228b2d47af..ac9d34d7cfd 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected @@ -171,5 +171,7 @@ | taint.cpp:208:6:208:6 | 0 | taint.cpp:216:7:216:7 | y | | | taint.cpp:213:12:213:12 | ref arg x | taint.cpp:213:12:213:12 | x | | | taint.cpp:213:12:213:12 | ref arg x | taint.cpp:215:7:215:7 | x | | +| taint.cpp:213:12:213:12 | x | taint.cpp:213:15:213:15 | ref arg y | | | taint.cpp:213:15:213:15 | ref arg y | taint.cpp:213:15:213:15 | y | | | taint.cpp:213:15:213:15 | ref arg y | taint.cpp:216:7:216:7 | y | | +| taint.cpp:213:15:213:15 | y | taint.cpp:213:12:213:12 | ref arg x | | diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp index b2ad4f790be..90d043dd45b 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp @@ -213,5 +213,5 @@ void test_swap() { std::swap(x, y); sink(x); // [FALSE POSITIVE] - sink(y); // tainted [NOT DETECTED] + sink(y); // tainted } 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 f0e101127e5..dd03a3b49c5 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected @@ -16,3 +16,4 @@ | taint.cpp:195:7:195:7 | x | taint.cpp:193:6:193:6 | x | | taint.cpp:210:7:210:7 | x | taint.cpp:207:6:207:11 | call to source | | taint.cpp:215:7:215:7 | x | taint.cpp:207:6:207:11 | call to source | +| taint.cpp:216:7:216:7 | y | taint.cpp:207:6:207:11 | 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 4cf348d9b37..5718971a4ac 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 @@ -8,3 +8,4 @@ | taint.cpp:192:23:192:28 | taint.cpp:195:7:195:7 | AST only | | taint.cpp:193:6:193:6 | taint.cpp:195:7:195:7 | AST only | | taint.cpp:207:6:207:11 | taint.cpp:215:7:215:7 | AST only | +| taint.cpp:207:6:207:11 | taint.cpp:216:7:216:7 | AST only |