@@ -166,7 +166,7 @@ private predicate instructionTaintStep(Instruction i1, Instruction i2) {
166166 i2 = any ( CallInstruction call |
167167 exists ( int indexIn |
168168 modelTaintToReturnValue ( call .getStaticCallTarget ( ) , indexIn ) and
169- i1 = call . getPositionalArgument ( indexIn )
169+ i1 = getACallArgumentOrIndirection ( call , indexIn )
170170 )
171171 )
172172 or
@@ -178,13 +178,28 @@ private predicate instructionTaintStep(Instruction i1, Instruction i2) {
178178 i2 = any ( WriteSideEffectInstruction outNode |
179179 exists ( CallInstruction call , int indexIn , int indexOut |
180180 modelTaintToParameter ( call .getStaticCallTarget ( ) , indexIn , indexOut ) and
181- i1 = call . getPositionalArgument ( indexIn ) and
181+ i1 = getACallArgumentOrIndirection ( call , indexIn ) and
182182 outNode .getIndex ( ) = indexOut and
183183 outNode .getPrimaryInstruction ( ) = call
184184 )
185185 )
186186}
187187
188+ /**
189+ * Get an instruction that goes into argument `argumentIndex` of `call`. This
190+ * can be either directly or through one pointer indirection.
191+ */
192+ private Instruction getACallArgumentOrIndirection ( CallInstruction call , int argumentIndex ) {
193+ result = call .getPositionalArgument ( argumentIndex )
194+ or
195+ exists ( ReadSideEffectInstruction readSE |
196+ // TODO: why are read side effect operands imprecise?
197+ result = readSE .getSideEffectOperand ( ) .getAnyDef ( ) and
198+ readSE .getPrimaryInstruction ( ) = call and
199+ readSE .getIndex ( ) = argumentIndex
200+ )
201+ }
202+
188203private predicate modelTaintToParameter ( Function f , int parameterIn , int parameterOut ) {
189204 exists ( FunctionInput modelIn , FunctionOutput modelOut |
190205 f .( TaintFunction ) .hasTaintFlow ( modelIn , modelOut ) and
0 commit comments