@@ -80,6 +80,35 @@ Function getStateMachineImplementation(Function stub) {
8080 isStateMachineImplementation ( stub , result )
8181}
8282
83+ /**
84+ * Materialized: holds if function `caller` contains a call to function `callee`
85+ * via a static target (direct call).
86+ */
87+ pragma [ nomagic]
88+ private predicate callsViaStaticTarget ( Function caller , Function callee ) {
89+ callee = any ( CallInstruction call | call .getEnclosingFunction ( ) = caller ) .getStaticTarget ( )
90+ }
91+
92+ /**
93+ * Materialized: holds if function `caller` contains a call to a function
94+ * with fully qualified name `calleeFqn` via an external reference.
95+ */
96+ pragma [ nomagic]
97+ private predicate callsViaExternalRef ( Function caller , string calleeFqn ) {
98+ exists ( CallInstruction call |
99+ call .getEnclosingFunction ( ) = caller and
100+ calleeFqn = call .getTargetOperand ( ) .getAnyDef ( ) .( ExternalRefInstruction ) .getFullyQualifiedName ( )
101+ )
102+ }
103+
104+ /**
105+ * Materialized: maps functions to their fully qualified names.
106+ */
107+ pragma [ nomagic]
108+ private predicate functionFqn ( Function f , string fqn ) {
109+ fqn = f .getFullyQualifiedName ( )
110+ }
111+
83112/**
84113 * Gets a method that transitively calls a vulnerable method.
85114 * This computes the transitive closure of the call graph.
@@ -91,26 +120,19 @@ Function getAVulnerableMethod(string id) {
91120 // Direct call to vulnerable method
92121 result = getADirectlyVulnerableMethod ( id )
93122 or
94- // Transitive: method calls another method that is vulnerable (via ExternalRef for external calls)
95- exists ( CallInstruction call , Function callee |
96- call .getEnclosingFunction ( ) = result and
97- callee = getAVulnerableMethod ( id ) and
98- call .getTargetOperand ( ) .getAnyDef ( ) .( ExternalRefInstruction ) .getFullyQualifiedName ( ) =
99- callee .getFullyQualifiedName ( )
100- )
123+ // Transitive: method calls a vulnerable method via static target
124+ callsViaStaticTarget ( result , getAVulnerableMethod ( id ) )
101125 or
102- // Transitive: method calls another method that is vulnerable (via static target for direct calls)
103- exists ( CallInstruction call |
104- call .getEnclosingFunction ( ) = result and
105- call .getStaticTarget ( ) = getAVulnerableMethod ( id )
126+ // Transitive: method calls a vulnerable method via external reference
127+ exists ( Function callee , string calleeFqn |
128+ callee = getAVulnerableMethod ( id ) and
129+ functionFqn ( callee , calleeFqn ) and
130+ callsViaExternalRef ( result , calleeFqn )
106131 )
107132 or
108133 // Iterator/async: if a state machine's MoveNext is vulnerable,
109134 // the stub method that creates it is also vulnerable
110- exists ( Function stateMachine |
111- stateMachine = getAVulnerableMethod ( id ) and
112- isStateMachineImplementation ( result , stateMachine )
113- )
135+ isStateMachineImplementation ( result , getAVulnerableMethod ( id ) )
114136}
115137
116138/**
0 commit comments