@@ -7,9 +7,10 @@ import cpp
77import semmle.code.cpp.security.TaintTrackingImpl as ASTTaintTracking
88import semmle.code.cpp.ir.dataflow.DefaultTaintTracking as IRDefaultTaintTracking
99import IRDefaultTaintTracking:: TaintedWithPath as TaintedWithPath
10+ import TaintedWithPath:: Private
1011import TestUtilities.InlineExpectationsTest
1112
12- predicate isSink ( Element sink ) {
13+ predicate isSinkArgument ( Element sink ) {
1314 exists ( FunctionCall call |
1415 call .getTarget ( ) .getName ( ) = "sink" and
1516 sink = call .getAnArgument ( )
@@ -19,31 +20,34 @@ predicate isSink(Element sink) {
1920predicate astTaint ( Expr source , Element sink ) { ASTTaintTracking:: tainted ( source , sink ) }
2021
2122class SourceConfiguration extends TaintedWithPath:: TaintTrackingConfiguration {
22- override predicate isSink ( Element e ) { any ( ) }
23+ override predicate isSink ( Element e ) { isSinkArgument ( e ) }
2324}
2425
25- predicate irTaint ( Expr source , Element sink ) {
26- TaintedWithPath:: taintedWithPath ( source , sink , _, _)
26+ predicate irTaint ( Element source , Element sink , string tag ) {
27+ exists ( TaintedWithPath:: PathNode sinkNode , TaintedWithPath:: PathNode predNode |
28+ TaintedWithPath:: taintedWithPath ( source , _, _, sinkNode ) and
29+ predNode = getAPredecessor * ( sinkNode ) and
30+ sink = getElementFromPathNode ( predNode ) and
31+ // Make sure the path is actually reachable from this predecessor.
32+ // Otherwise, we could pick `predNode` to be b when `source` is
33+ // `source1` in this dataflow graph:
34+ // source1 ---> a ---> c ---> sinkNode
35+ // ^
36+ // source2 ---> b --/
37+ source = getElementFromPathNode ( getAPredecessor * ( predNode ) ) and
38+ if sinkNode = predNode then tag = "ir-sink" else tag = "ir-path"
39+ )
2740}
2841
2942class IRDefaultTaintTrackingTest extends InlineExpectationsTest {
3043 IRDefaultTaintTrackingTest ( ) { this = "IRDefaultTaintTrackingTest" }
3144
32- override string getARelevantTag ( ) { result = "ir" }
45+ override string getARelevantTag ( ) { result = [ "ir-path" , "ir-sink" ] }
3346
3447 override predicate hasActualResult ( Location location , string element , string tag , string value ) {
35- exists ( Expr source , Element tainted , int n |
36- tag = "ir" and
37- irTaint ( source , tainted ) and
38- (
39- isSink ( tainted )
40- or
41- exists ( Element sink |
42- isSink ( sink ) and
43- irTaint ( tainted , sink )
44- )
45- ) and
46- n = strictcount ( Expr otherSource | irTaint ( otherSource , tainted ) ) and
48+ exists ( Element source , Element tainted , int n |
49+ irTaint ( source , tainted , tag ) and
50+ n = strictcount ( Element otherSource | irTaint ( otherSource , tainted , _) ) and
4751 (
4852 n = 1 and value = ""
4953 or
@@ -70,10 +74,10 @@ class ASTTaintTrackingTest extends InlineExpectationsTest {
7074 tag = "ast" and
7175 astTaint ( source , tainted ) and
7276 (
73- isSink ( tainted )
77+ isSinkArgument ( tainted )
7478 or
7579 exists ( Element sink |
76- isSink ( sink ) and
80+ isSinkArgument ( sink ) and
7781 astTaint ( tainted , sink )
7882 )
7983 ) and
0 commit comments