@@ -611,19 +611,7 @@ private newtype TLoadChain =
611
611
)
612
612
}
613
613
614
- /**
615
- * This class abstracts out the information needed to end a `LoadChain`. For now the only
616
- * implementation is `LoadChainEndInstructionLoad`, but we may need another implementation similar
617
- * to `StoreChainEndInstructionSideEffect` to handle cases like:
618
- * ```
619
- * void read_f(Inner* inner) {
620
- * sink(inner->f);
621
- * }
622
- * ...
623
- * outer.inner.f = taint();
624
- * read_f(&outer.inner);
625
- * ```
626
- */
614
+ /** This class abstracts out the information needed to end a `LoadChain`. */
627
615
abstract private class LoadChainEndInstruction extends Instruction {
628
616
abstract FieldAddressInstruction getFieldInstruction ( ) ;
629
617
@@ -643,6 +631,32 @@ private class LoadChainEndInstructionLoad extends LoadChainEndInstruction, LoadI
643
631
override Instruction getReadValue ( ) { result = getSourceValueOperand ( ) .getAnyDef ( ) }
644
632
}
645
633
634
+ /**
635
+ * Ends a `LoadChain` with a `ReadSideEffectInstruction`. This ensures that we pop content from the
636
+ * access path when passing an argument that reads a field. For example in:
637
+ * ```
638
+ * void read_f(Inner* inner) {
639
+ * sink(inner->f);
640
+ * }
641
+ * ...
642
+ * outer.inner.f = taint();
643
+ * read_f(&outer.inner);
644
+ * ```
645
+ * In order to register `inner->f` as a `readStep`, the head of the access path must
646
+ * be `f`, and thus reading `&outer.inner` must pop `inner` from the access path
647
+ * before entering `read_f`.
648
+ */
649
+ private class LoadChainInstructionSideEffect extends LoadChainEndInstruction ,
650
+ ReadSideEffectInstruction {
651
+ FieldAddressInstruction fi ;
652
+
653
+ LoadChainInstructionSideEffect ( ) { fi = skipConversion * ( this .getArgumentDef ( ) ) }
654
+
655
+ override FieldAddressInstruction getFieldInstruction ( ) { result = fi }
656
+
657
+ override Instruction getReadValue ( ) { result = getSideEffectOperand ( ) .getAnyDef ( ) }
658
+ }
659
+
646
660
/**
647
661
* A `LoadChain` represents a series of field lookups that compute the source address of a load.
648
662
* For example, given the field lookup in `f(a.b.c)`, there are two `LoadChains`s:
0 commit comments