@@ -33,7 +33,7 @@ predicate flowIntoParameter(
3333 not f .isVirtual ( ) and
3434 call .getPositionalArgument ( n ) = instr and
3535 f = call .getStaticCallTarget ( ) and
36- init . getEnclosingFunction ( ) = f and
36+ getEnclosingNonVirtualFunctionInitializeParameter ( init , f ) and
3737 init .getParameter ( ) .getIndex ( ) = unbind ( n )
3838}
3939
@@ -62,7 +62,7 @@ predicate getThisArgumentInitParam(
6262) {
6363 not f .isVirtual ( ) and
6464 call .getStaticCallTarget ( ) = f and
65- init . getEnclosingFunction ( ) = f and
65+ getEnclosingNonVirtualFunctionInitializeParameter ( init , f ) and
6666 call .getThisArgument ( ) = instr and
6767 init .getIRVariable ( ) instanceof IRThisVariable
6868}
@@ -94,13 +94,19 @@ predicate isSource(InitializeParameterInstruction init, string msg, Class c) {
9494 init .getEnclosingFunction ( ) .getDeclaringType ( ) = c
9595}
9696
97- /** Holds if `instr` flows to a sink. */
98- predicate flowsToSink ( Instruction instr ) {
99- isSink ( instr , _, _)
100- or
101- exists ( Instruction mid |
102- successor ( instr , mid ) and
103- flowsToSink ( mid )
97+ /**
98+ * Holds if `instr` flows to a sink (which is a use of the value of `instr` as a `this` pointer
99+ * of type `sinkClass`).
100+ */
101+ predicate flowsToSink ( Instruction instr , Instruction sink , Class sinkClass ) {
102+ flowsFromSource ( instr ) and
103+ (
104+ isSink ( instr , _, sinkClass ) and instr = sink
105+ or
106+ exists ( Instruction mid |
107+ successor ( instr , mid ) and
108+ flowsToSink ( mid , sink , sinkClass )
109+ )
104110 )
105111}
106112
@@ -114,59 +120,67 @@ predicate flowsFromSource(Instruction instr) {
114120 )
115121}
116122
123+ /** Holds if `f` is the enclosing non-virtual function of `init`. */
124+ predicate getEnclosingNonVirtualFunctionInitializeParameter (
125+ InitializeParameterInstruction init , Function f
126+ ) {
127+ not f .isVirtual ( ) and
128+ init .getEnclosingFunction ( ) = f
129+ }
130+
131+ /** Holds if `f` is the enclosing non-virtual function of `init`. */
132+ predicate getEnclosingNonVirtualFunctionInitializeIndirection (
133+ InitializeIndirectionInstruction init , Function f
134+ ) {
135+ not f .isVirtual ( ) and
136+ init .getEnclosingFunction ( ) = f
137+ }
138+
117139/**
118140 * Holds if `instr` is an argument (or argument indirection) to a call, and
119141 * `succ` is the corresponding initialization instruction in the call target.
120142 */
121143predicate flowThroughCallable ( Instruction instr , Instruction succ ) {
122- flowsToSink ( succ ) and
123- (
124- // Flow from an argument to a parameter
125- exists ( CallInstruction call , InitializeParameterInstruction init | init = succ |
126- getPositionalArgumentInitParam ( call , instr , init , call .getStaticCallTarget ( ) )
127- or
128- getThisArgumentInitParam ( call , instr , init , call .getStaticCallTarget ( ) )
129- )
144+ // Flow from an argument to a parameter
145+ exists ( CallInstruction call , InitializeParameterInstruction init | init = succ |
146+ getPositionalArgumentInitParam ( call , instr , init , call .getStaticCallTarget ( ) )
130147 or
131- // Flow from argument indirection to parameter indirection
132- exists (
133- CallInstruction call , ReadSideEffectInstruction read , InitializeIndirectionInstruction init
134- |
135- init = succ and
136- read .getPrimaryInstruction ( ) = call and
137- init .getEnclosingFunction ( ) = call .getStaticCallTarget ( )
138- |
139- exists ( int n |
140- read .getSideEffectOperand ( ) .getAnyDef ( ) = instr and
141- read .getIndex ( ) = n and
142- init .getParameter ( ) .getIndex ( ) = unbind ( n )
143- )
144- or
145- call .getThisArgument ( ) = instr and
146- init .getIRVariable ( ) instanceof IRThisVariable
148+ getThisArgumentInitParam ( call , instr , init , call .getStaticCallTarget ( ) )
149+ )
150+ or
151+ // Flow from argument indirection to parameter indirection
152+ exists (
153+ CallInstruction call , ReadSideEffectInstruction read , InitializeIndirectionInstruction init
154+ |
155+ init = succ and
156+ read .getPrimaryInstruction ( ) = call and
157+ getEnclosingNonVirtualFunctionInitializeIndirection ( init , call .getStaticCallTarget ( ) )
158+ |
159+ exists ( int n |
160+ read .getSideEffectOperand ( ) .getAnyDef ( ) = instr and
161+ read .getIndex ( ) = n and
162+ init .getParameter ( ) .getIndex ( ) = unbind ( n )
147163 )
164+ or
165+ call .getThisArgument ( ) = instr and
166+ init .getIRVariable ( ) instanceof IRThisVariable
148167 )
149168}
150169
151170/** Holds if `instr` flows to `succ`. */
152171predicate successor ( Instruction instr , Instruction succ ) {
153- flowsToSink ( succ ) and
172+ succ . getBlock ( ) . postDominates ( instr . getBlock ( ) ) and
154173 (
155- irBbPostDominates ( succ .getBlock ( ) , instr .getBlock ( ) ) and
156- (
157- succ .( CopyInstruction ) .getSourceValue ( ) = instr or
158- succ .( CheckedConvertOrNullInstruction ) .getUnary ( ) = instr or
159- succ .( ChiInstruction ) .getTotal ( ) = instr or
160- succ .( ConvertInstruction ) .getUnary ( ) = instr or
161- succ .( InheritanceConversionInstruction ) .getUnary ( ) = instr
162- )
163- or
164- flowThroughCallable ( instr , succ )
174+ succ .( CopyInstruction ) .getSourceValue ( ) = instr or
175+ succ .( CheckedConvertOrNullInstruction ) .getUnary ( ) = instr or
176+ succ .( ChiInstruction ) .getTotal ( ) = instr or
177+ succ .( ConvertInstruction ) .getUnary ( ) = instr or
178+ succ .( InheritanceConversionInstruction ) .getUnary ( ) = instr
165179 )
180+ or
181+ flowThroughCallable ( instr , succ )
166182}
167183
168- predicate successorTC ( Instruction i1 , Instruction i2 ) = fastTC( successor / 2 ) ( i1 , i2 )
169-
170184/**
171185 * Holds if:
172186 * - `source` is an initialization of a `this` pointer of type `sourceClass`, and
@@ -179,17 +193,14 @@ predicate flows(
179193 Class sinkClass
180194) {
181195 isSource ( source , msg , sourceClass ) and
182- successorTC ( source , sink ) and
196+ flowsToSink ( source , sink , sinkClass ) and
183197 isSink ( sink , call , sinkClass )
184198}
185199
186- query predicate edges ( Instruction a , Instruction b ) {
187- successor ( a , b ) and flowsFromSource ( a ) and flowsFromSource ( b )
188- }
200+ query predicate edges ( Instruction a , Instruction b ) { successor ( a , b ) and flowsToSink ( b , _, _) }
189201
190202query predicate nodes ( Instruction n , string key , string val ) {
191- flowsFromSource ( n ) and
192- flowsToSink ( n ) and
203+ flowsToSink ( n , _, _) and
193204 key = "semmle.label" and
194205 val = n .toString ( )
195206}
0 commit comments