@@ -508,7 +508,10 @@ predicate localFlowStep(Node nodeFrom, Node nodeTo) { simpleLocalFlowStep(nodeFr
508508 * data flow. It may have less flow than the `localFlowStep` predicate.
509509 */
510510predicate simpleLocalFlowStep ( Node nodeFrom , Node nodeTo ) {
511- simpleInstructionLocalFlowStep ( nodeFrom .asInstruction ( ) , nodeTo .asInstruction ( ) )
511+ simpleInstructionLocalFlowStep ( nodeFrom .asOperand ( ) , nodeTo .asInstruction ( ) )
512+ or
513+ // Flow from an instruction to its operands
514+ nodeTo .asOperand ( ) .getAnyDef ( ) = nodeFrom .asInstruction ( )
512515}
513516
514517pragma [ noinline]
@@ -521,15 +524,15 @@ private predicate getFieldSizeOfClass(Class c, Type type, int size) {
521524}
522525
523526cached
524- private predicate simpleInstructionLocalFlowStep ( Instruction iFrom , Instruction iTo ) {
525- iTo .( CopyInstruction ) .getSourceValue ( ) = iFrom
527+ private predicate simpleInstructionLocalFlowStep ( Operand opFrom , Instruction iTo ) {
528+ iTo .( CopyInstruction ) .getSourceValue ( ) = opFrom . getDef ( )
526529 or
527- iTo .( PhiInstruction ) .getAnOperand ( ) .getDef ( ) = iFrom
530+ iTo .( PhiInstruction ) .getAnInput ( ) = opFrom .getDef ( )
528531 or
529532 // A read side effect is almost never exact since we don't know exactly how
530533 // much memory the callee will read.
531- iTo .( ReadSideEffectInstruction ) .getSideEffectOperand ( ) . getAnyDef ( ) = iFrom and
532- not iFrom .isResultConflated ( )
534+ iTo .( ReadSideEffectInstruction ) .getSideEffectOperand ( ) = opFrom and
535+ not opFrom . getAnyDef ( ) .isResultConflated ( )
533536 or
534537 // Loading a single `int` from an `int *` parameter is not an exact load since
535538 // the parameter may point to an entire array rather than a single `int`. The
@@ -542,7 +545,7 @@ private predicate simpleInstructionLocalFlowStep(Instruction iFrom, Instruction
542545 // reassignment of the parameter indirection, including a conditional one that
543546 // leads to a phi node.
544547 exists ( InitializeIndirectionInstruction init |
545- iFrom = init and
548+ opFrom . getAnyDef ( ) = init and
546549 iTo .( LoadInstruction ) .getSourceValueOperand ( ) .getAnyDef ( ) = init and
547550 // Check that the types match. Otherwise we can get flow from an object to
548551 // its fields, which leads to field conflation when there's flow from other
@@ -552,11 +555,11 @@ private predicate simpleInstructionLocalFlowStep(Instruction iFrom, Instruction
552555 )
553556 or
554557 // Treat all conversions as flow, even conversions between different numeric types.
555- iTo .( ConvertInstruction ) .getUnary ( ) = iFrom
558+ iTo .( ConvertInstruction ) .getUnary ( ) = opFrom . getDef ( )
556559 or
557- iTo .( CheckedConvertOrNullInstruction ) .getUnary ( ) = iFrom
560+ iTo .( CheckedConvertOrNullInstruction ) .getUnary ( ) = opFrom . getDef ( )
558561 or
559- iTo .( InheritanceConversionInstruction ) .getUnary ( ) = iFrom
562+ iTo .( InheritanceConversionInstruction ) .getUnary ( ) = opFrom . getDef ( )
560563 or
561564 // A chi instruction represents a point where a new value (the _partial_
562565 // operand) may overwrite an old value (the _total_ operand), but the alias
@@ -569,7 +572,7 @@ private predicate simpleInstructionLocalFlowStep(Instruction iFrom, Instruction
569572 //
570573 // Flow through the partial operand belongs in the taint-tracking libraries
571574 // for now.
572- iTo .getAnOperand ( ) .( ChiTotalOperand ) . getDef ( ) = iFrom
575+ iTo .getAnOperand ( ) .( ChiTotalOperand ) = opFrom
573576 or
574577 // Add flow from write side-effects to non-conflated chi instructions through their
575578 // partial operands. From there, a `readStep` will find subsequent reads of that field.
@@ -584,24 +587,25 @@ private predicate simpleInstructionLocalFlowStep(Instruction iFrom, Instruction
584587 // Here, a `WriteSideEffectInstruction` will provide a new definition for `p->x` after the call to
585588 // `setX`, which will be melded into `p` through a chi instruction.
586589 exists ( ChiInstruction chi | chi = iTo |
587- chi .getPartialOperand ( ) .getDef ( ) = iFrom .( WriteSideEffectInstruction ) and
590+ opFrom .getAnyDef ( ) instanceof WriteSideEffectInstruction and
591+ chi .getPartialOperand ( ) = opFrom and
588592 not chi .isResultConflated ( )
589593 )
590594 or
591595 // Flow from stores to structs with a single field to a load of that field.
592- iTo .( LoadInstruction ) .getSourceValueOperand ( ) . getAnyDef ( ) = iFrom and
596+ iTo .( LoadInstruction ) .getSourceValueOperand ( ) = opFrom and
593597 exists ( int size , Type type , Class cTo |
594- type = iFrom .getResultType ( ) and
598+ type = opFrom . getAnyDef ( ) .getResultType ( ) and
595599 cTo = iTo .getResultType ( ) and
596600 cTo .getSize ( ) = size and
597601 getFieldSizeOfClass ( cTo , type , size )
598602 )
599603 or
600604 // Flow through modeled functions
601- modelFlow ( iFrom , iTo )
605+ modelFlow ( opFrom , iTo )
602606}
603607
604- private predicate modelFlow ( Instruction iFrom , Instruction iTo ) {
608+ private predicate modelFlow ( Operand opFrom , Instruction iTo ) {
605609 exists (
606610 CallInstruction call , DataFlowFunction func , FunctionInput modelIn , FunctionOutput modelOut
607611 |
@@ -626,17 +630,17 @@ private predicate modelFlow(Instruction iFrom, Instruction iTo) {
626630 (
627631 exists ( int index |
628632 modelIn .isParameter ( index ) and
629- iFrom = call .getPositionalArgument ( index )
633+ opFrom = call .getPositionalArgumentOperand ( index )
630634 )
631635 or
632636 exists ( int index , ReadSideEffectInstruction read |
633637 modelIn .isParameterDeref ( index ) and
634638 read = getSideEffectFor ( call , index ) and
635- iFrom = read .getSideEffectOperand ( ) . getAnyDef ( )
639+ opFrom = read .getSideEffectOperand ( )
636640 )
637641 or
638642 modelIn .isQualifierAddress ( ) and
639- iFrom = call .getThisArgument ( )
643+ opFrom = call .getThisArgumentOperand ( )
640644 // TODO: add read side effects for qualifiers
641645 )
642646 )
0 commit comments