@@ -181,24 +181,41 @@ private class CollectionContent extends Content, TCollectionContent {
181181}
182182
183183private class ArrayContent extends Content , TArrayContent {
184- override string toString ( ) { result = "array" }
184+ ArrayContent ( ) { this = TArrayContent ( ) }
185+
186+ override string toString ( ) { result = "array content" }
185187}
186188
187- private predicate storeStepNoChi ( Node node1 , Content f , PostUpdateNode node2 ) {
189+ private predicate fieldStoreStepNoChi ( Node node1 , FieldContent f , PostUpdateNode node2 ) {
188190 exists ( FieldAddressInstruction fa , StoreInstruction store |
189191 store = node2 .asInstruction ( ) and
190192 store .getDestinationAddress ( ) = fa and
191193 store .getSourceValue ( ) = node1 .asInstruction ( ) and
192- f .( FieldContent ) . getField ( ) = fa .getField ( )
194+ f .getField ( ) = fa .getField ( )
193195 )
194196}
195197
196- private predicate storeStepChi ( Node node1 , Content f , PostUpdateNode node2 ) {
198+ private predicate fieldStoreStepChi ( Node node1 , FieldContent f , PostUpdateNode node2 ) {
197199 exists ( FieldAddressInstruction fa , StoreInstruction store |
198200 node1 .asInstruction ( ) = store and
199201 store .getDestinationAddress ( ) = fa and
200202 node2 .asInstruction ( ) .( ChiInstruction ) .getPartial ( ) = store and
201- f .( FieldContent ) .getField ( ) = fa .getField ( )
203+ f .getField ( ) = fa .getField ( )
204+ )
205+ }
206+
207+ private predicate arrayStoreStepChi ( Node node1 , Content a , PostUpdateNode node2 ) {
208+ a instanceof ArrayContent and
209+ exists ( StoreInstruction store |
210+ node1 .asInstruction ( ) = store and
211+ (
212+ // `x[i] = taint()`
213+ store .getDestinationAddress ( ) instanceof PointerAddInstruction
214+ or
215+ // `*p = taint()`
216+ store .getDestinationAddress ( ) .( CopyValueInstruction ) .getUnary ( ) instanceof LoadInstruction
217+ ) and
218+ node2 .asInstruction ( ) .( ChiInstruction ) .getPartial ( ) = store
202219 )
203220}
204221
@@ -208,16 +225,12 @@ private predicate storeStepChi(Node node1, Content f, PostUpdateNode node2) {
208225 * value of `node1`.
209226 */
210227predicate storeStep ( Node node1 , Content f , PostUpdateNode node2 ) {
211- storeStepNoChi ( node1 , f , node2 ) or
212- storeStepChi ( node1 , f , node2 )
228+ fieldStoreStepNoChi ( node1 , f , node2 ) or
229+ fieldStoreStepChi ( node1 , f , node2 ) or
230+ arrayStoreStepChi ( node1 , f , node2 )
213231}
214232
215- /**
216- * Holds if data can flow from `node1` to `node2` via a read of `f`.
217- * Thus, `node1` references an object with a field `f` whose value ends up in
218- * `node2`.
219- */
220- predicate readStep ( Node node1 , Content f , Node node2 ) {
233+ private predicate fieldReadStep ( Node node1 , FieldContent f , Node node2 ) {
221234 exists ( FieldAddressInstruction fa , LoadInstruction load |
222235 load .getSourceAddress ( ) = fa and
223236 node1 .asInstruction ( ) = load .getSourceValueOperand ( ) .getAnyDef ( ) and
@@ -226,6 +239,24 @@ predicate readStep(Node node1, Content f, Node node2) {
226239 )
227240}
228241
242+ private predicate arrayReadStep ( Node node1 , ArrayContent a , Node node2 ) {
243+ a = TArrayContent ( ) and
244+ exists ( LoadInstruction load |
245+ node1 .asInstruction ( ) = load .getSourceValueOperand ( ) .getAnyDef ( ) and
246+ load = node2 .asInstruction ( )
247+ )
248+ }
249+
250+ /**
251+ * Holds if data can flow from `node1` to `node2` via a read of `f`.
252+ * Thus, `node1` references an object with a field `f` whose value ends up in
253+ * `node2`.
254+ */
255+ predicate readStep ( Node node1 , Content f , Node node2 ) {
256+ fieldReadStep ( node1 , f , node2 ) or
257+ arrayReadStep ( node1 , f , node2 )
258+ }
259+
229260/**
230261 * Holds if values stored inside content `c` are cleared at node `n`.
231262 */
0 commit comments