@@ -239,8 +239,6 @@ abstract class PostUpdateNode extends InstructionNode {
239239}
240240
241241/**
242- * INTERNAL: do not use.
243- *
244242 * The base class for nodes that perform "partial definitions".
245243 *
246244 * In contrast to a normal "definition", which provides a new value for
@@ -253,7 +251,7 @@ abstract class PostUpdateNode extends InstructionNode {
253251 * setY(&x); // a partial definition of the object `x`.
254252 * ```
255253 */
256- abstract class PartialDefinitionNode extends PostUpdateNode , TInstructionNode { }
254+ abstract private class PartialDefinitionNode extends PostUpdateNode , TInstructionNode { }
257255
258256private class ExplicitFieldStoreQualifierNode extends PartialDefinitionNode {
259257 override ChiInstruction instr ;
@@ -272,17 +270,6 @@ private class ExplicitFieldStoreQualifierNode extends PartialDefinitionNode {
272270 override Node getPreUpdateNode ( ) { result .asInstruction ( ) = instr .getTotal ( ) }
273271}
274272
275- private class FieldStoreWriteSideEffectNode extends PartialDefinitionNode {
276- override ChiInstruction instr ;
277-
278- FieldStoreWriteSideEffectNode ( ) {
279- not instr .isResultConflated ( ) and
280- exists ( WriteSideEffectInstruction sideEffect | instr .getPartial ( ) = sideEffect )
281- }
282-
283- override Node getPreUpdateNode ( ) { result .asInstruction ( ) = instr .getTotal ( ) }
284- }
285-
286273/**
287274 * Not every store instruction generates a chi instruction that we can attach a PostUpdateNode to.
288275 * For instance, an update to a field of a struct containing only one field. For these cases we
@@ -434,32 +421,6 @@ predicate localFlowStep(Node nodeFrom, Node nodeTo) { simpleLocalFlowStep(nodeFr
434421 */
435422predicate simpleLocalFlowStep ( Node nodeFrom , Node nodeTo ) {
436423 simpleInstructionLocalFlowStep ( nodeFrom .asInstruction ( ) , nodeTo .asInstruction ( ) )
437- or
438- // The next two rules allow flow from partial definitions in setters to succeeding loads in the caller.
439- // First, we add flow from write side-effects to non-conflated chi instructions through their
440- // partial operands. Consider the following example:
441- // ```
442- // void setX(Point* p, int new_x) {
443- // p->x = new_x;
444- // }
445- // ...
446- // setX(&p, taint());
447- // ```
448- // Here, a `WriteSideEffectInstruction` will provide a new definition for `p->x` after the call to
449- // `setX`, which will be melded into `p` through a chi instruction.
450- nodeTo instanceof FieldStoreWriteSideEffectNode and
451- exists ( ChiInstruction chi | chi = nodeTo .asInstruction ( ) |
452- chi .getPartialOperand ( ) .getDef ( ) = nodeFrom .asInstruction ( ) .( WriteSideEffectInstruction ) and
453- not chi .isResultConflated ( )
454- )
455- or
456- // Next, we add flow from non-conflated chi instructions to loads (even when they are not precise).
457- // This ensures that loads of `p->x` gets data flow from the `WriteSideEffectInstruction` above.
458- nodeFrom instanceof FieldStoreWriteSideEffectNode and
459- exists ( ChiInstruction chi | chi = nodeFrom .asInstruction ( ) |
460- not chi .isResultConflated ( ) and
461- nodeTo .asInstruction ( ) .( LoadInstruction ) .getSourceValueOperand ( ) .getAnyDef ( ) = chi
462- )
463424}
464425
465426pragma [ noinline]
@@ -497,6 +458,23 @@ private predicate simpleInstructionLocalFlowStep(Instruction iFrom, Instruction
497458 // for now.
498459 iTo .getAnOperand ( ) .( ChiTotalOperand ) .getDef ( ) = iFrom
499460 or
461+ // Add flow from write side-effects to non-conflated chi instructions through their
462+ // partial operands. From there, a `readStep` will find subsequent reads of that field.
463+ // Consider the following example:
464+ // ```
465+ // void setX(Point* p, int new_x) {
466+ // p->x = new_x;
467+ // }
468+ // ...
469+ // setX(&p, taint());
470+ // ```
471+ // Here, a `WriteSideEffectInstruction` will provide a new definition for `p->x` after the call to
472+ // `setX`, which will be melded into `p` through a chi instruction.
473+ exists ( ChiInstruction chi | chi = iTo |
474+ chi .getPartialOperand ( ) .getDef ( ) = iFrom .( WriteSideEffectInstruction ) and
475+ not chi .isResultConflated ( )
476+ )
477+ or
500478 // Flow from stores to structs with a single field to a load of that field.
501479 iTo .( LoadInstruction ) .getSourceValueOperand ( ) .getAnyDef ( ) = iFrom and
502480 exists ( int size , Type type |
0 commit comments