@@ -41,6 +41,9 @@ predicate localTaintStep(DataFlow::Node src, DataFlow::Node sink) {
4141predicate localAdditionalTaintStep ( DataFlow:: Node src , DataFlow:: Node sink ) {
4242 localAdditionalTaintExprStep ( src .asExpr ( ) , sink .asExpr ( ) )
4343 or
44+ localAdditionalTaintUpdateStep ( src .asExpr ( ) ,
45+ sink .( DataFlow:: PostUpdateNode ) .getPreUpdateNode ( ) .asExpr ( ) )
46+ or
4447 exists ( Argument arg |
4548 src .asExpr ( ) = arg and
4649 arg .isVararg ( ) and
@@ -105,37 +108,47 @@ private predicate localAdditionalTaintExprStep(Expr src, Expr sink) {
105108 or
106109 sink .( LogicExpr ) .getAnOperand ( ) = src
107110 or
108- exists ( Assignment assign | assign .getSource ( ) = src |
109- sink = assign .getDest ( ) .( ArrayAccess ) .getArray ( )
110- )
111- or
112111 exists ( EnhancedForStmt for , SsaExplicitUpdate v |
113112 for .getExpr ( ) = src and
114113 v .getDefiningExpr ( ) = for .getVariable ( ) and
115114 v .getAFirstUse ( ) = sink
116115 )
117116 or
118- containerStep ( src , sink )
117+ containerReturnValueStep ( src , sink )
119118 or
120119 constructorStep ( src , sink )
121120 or
122121 qualifierToMethodStep ( src , sink )
123122 or
124- qualifierToArgumentStep ( src , sink )
125- or
126123 argToMethodStep ( src , sink )
127124 or
128- argToArgStep ( src , sink )
129- or
130- argToQualifierStep ( src , sink )
131- or
132125 comparisonStep ( src , sink )
133126 or
134127 stringBuilderStep ( src , sink )
135128 or
136129 serializationStep ( src , sink )
137130}
138131
132+ /**
133+ * Holds if taint can flow in one local step from `src` to `sink` excluding
134+ * local data flow steps. That is, `src` and `sink` are likely to represent
135+ * different objects.
136+ * This is restricted to cases where the step updates the value of `sink`.
137+ */
138+ private predicate localAdditionalTaintUpdateStep ( Expr src , Expr sink ) {
139+ exists ( Assignment assign | assign .getSource ( ) = src |
140+ sink = assign .getDest ( ) .( ArrayAccess ) .getArray ( )
141+ )
142+ or
143+ containerUpdateStep ( src , sink )
144+ or
145+ qualifierToArgumentStep ( src , sink )
146+ or
147+ argToArgStep ( src , sink )
148+ or
149+ argToQualifierStep ( src , sink )
150+ }
151+
139152private class BulkData extends RefType {
140153 BulkData ( ) {
141154 this .( Array ) .getElementType ( ) .( PrimitiveType ) .getName ( ) .regexpMatch ( "byte|char" )
@@ -242,7 +255,7 @@ private predicate constructorStep(Expr tracked, ConstructorCall sink) {
242255}
243256
244257/** Access to a method that passes taint from qualifier to argument. */
245- private predicate qualifierToArgumentStep ( Expr tracked , RValue sink ) {
258+ private predicate qualifierToArgumentStep ( Expr tracked , Expr sink ) {
246259 exists ( MethodAccess ma , int arg |
247260 taintPreservingQualifierToArgument ( ma .getMethod ( ) , arg ) and
248261 tracked = ma .getQualifier ( ) and
@@ -458,7 +471,7 @@ private predicate taintPreservingArgumentToMethod(Method method, int arg) {
458471 * Holds if `tracked` and `sink` are arguments to a method that transfers taint
459472 * between arguments.
460473 */
461- private predicate argToArgStep ( Expr tracked , RValue sink ) {
474+ private predicate argToArgStep ( Expr tracked , Expr sink ) {
462475 exists ( MethodAccess ma , Method method , int input , int output |
463476 taintPreservingArgToArg ( method , input , output ) and
464477 ma .getMethod ( ) = method and
0 commit comments