@@ -9,61 +9,72 @@ private import SsaImpl as Ssa
99private import semmle.code.cpp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
1010private import semmle.code.cpp.ir.dataflow.FlowSteps
1111
12- /**
13- * Holds if taint propagates from `nodeFrom` to `nodeTo` in exactly one local
14- * (intra-procedural) step. This relation is only used for local taint flow
15- * (for example `TaintTracking::localTaint(source, sink)`) so it may contain
16- * special cases that should only apply to local taint flow.
17- */
18- predicate localTaintStep ( DataFlow:: Node nodeFrom , DataFlow:: Node nodeTo ) {
19- // dataflow step
20- DataFlow:: localFlowStep ( nodeFrom , nodeTo )
21- or
22- // taint flow step
23- localAdditionalTaintStep ( nodeFrom , nodeTo , _)
24- or
25- // models-as-data summarized flow for local data flow (i.e. special case for flow
26- // through calls to modeled functions, without relying on global dataflow to join
27- // the dots).
28- FlowSummaryImpl:: Private:: Steps:: summaryThroughStepTaint ( nodeFrom , nodeTo , _)
29- }
30-
31- /**
32- * Holds if taint can flow in one local step from `nodeFrom` to `nodeTo` excluding
33- * local data flow steps. That is, `nodeFrom` and `nodeTo` are likely to represent
34- * different objects.
35- */
3612cached
37- predicate localAdditionalTaintStep ( DataFlow:: Node nodeFrom , DataFlow:: Node nodeTo , string model ) {
38- operandToInstructionTaintStep ( nodeFrom .asOperand ( ) , nodeTo .asInstruction ( ) ) and
39- model = ""
40- or
41- modeledTaintStep ( nodeFrom , nodeTo , model )
42- or
43- // Flow from (the indirection of) an operand of a pointer arithmetic instruction to the
44- // indirection of the pointer arithmetic instruction. This provides flow from `source`
45- // in `x[source]` to the result of the associated load instruction.
46- exists ( PointerArithmeticInstruction pai , int indirectionIndex |
47- nodeHasOperand ( nodeFrom , pai .getAnOperand ( ) , pragma [ only_bind_into ] ( indirectionIndex ) ) and
48- hasInstructionAndIndex ( nodeTo , pai , indirectionIndex + 1 )
49- ) and
50- model = ""
51- or
52- any ( Ssa:: Indirection ind ) .isAdditionalTaintStep ( nodeFrom , nodeTo ) and
53- model = ""
54- or
55- // models-as-data summarized flow
56- FlowSummaryImpl:: Private:: Steps:: summaryLocalStep ( nodeFrom .( FlowSummaryNode ) .getSummaryNode ( ) ,
57- nodeTo .( FlowSummaryNode ) .getSummaryNode ( ) , false , model )
58- or
59- // object->field conflation for content that is a `TaintInheritingContent`.
60- exists ( DataFlow:: ContentSet f |
61- readStep ( nodeFrom , f , nodeTo ) and
62- f .getAReadContent ( ) instanceof TaintInheritingContent
63- ) and
64- model = ""
13+ private module Cached {
14+ private import DataFlowImplCommon as DataFlowImplCommon
15+
16+ cached
17+ predicate forceCachingInSameStage ( ) { DataFlowImplCommon:: forceCachingInSameStage ( ) }
18+
19+ /**
20+ * Holds if taint propagates from `nodeFrom` to `nodeTo` in exactly one local
21+ * (intra-procedural) step. This relation is only used for local taint flow
22+ * (for example `TaintTracking::localTaint(source, sink)`) so it may contain
23+ * special cases that should only apply to local taint flow.
24+ */
25+ cached
26+ predicate localTaintStep ( DataFlow:: Node nodeFrom , DataFlow:: Node nodeTo ) {
27+ // dataflow step
28+ DataFlow:: localFlowStep ( nodeFrom , nodeTo )
29+ or
30+ // taint flow step
31+ localAdditionalTaintStep ( nodeFrom , nodeTo , _)
32+ or
33+ // models-as-data summarized flow for local data flow (i.e. special case for flow
34+ // through calls to modeled functions, without relying on global dataflow to join
35+ // the dots).
36+ FlowSummaryImpl:: Private:: Steps:: summaryThroughStepTaint ( nodeFrom , nodeTo , _)
37+ }
38+
39+ /**
40+ * Holds if taint can flow in one local step from `nodeFrom` to `nodeTo` excluding
41+ * local data flow steps. That is, `nodeFrom` and `nodeTo` are likely to represent
42+ * different objects.
43+ */
44+ cached
45+ predicate localAdditionalTaintStep ( DataFlow:: Node nodeFrom , DataFlow:: Node nodeTo , string model ) {
46+ operandToInstructionTaintStep ( nodeFrom .asOperand ( ) , nodeTo .asInstruction ( ) ) and
47+ model = ""
48+ or
49+ modeledTaintStep ( nodeFrom , nodeTo , model )
50+ or
51+ // Flow from (the indirection of) an operand of a pointer arithmetic instruction to the
52+ // indirection of the pointer arithmetic instruction. This provides flow from `source`
53+ // in `x[source]` to the result of the associated load instruction.
54+ exists ( PointerArithmeticInstruction pai , int indirectionIndex |
55+ nodeHasOperand ( nodeFrom , pai .getAnOperand ( ) , pragma [ only_bind_into ] ( indirectionIndex ) ) and
56+ hasInstructionAndIndex ( nodeTo , pai , indirectionIndex + 1 )
57+ ) and
58+ model = ""
59+ or
60+ any ( Ssa:: Indirection ind ) .isAdditionalTaintStep ( nodeFrom , nodeTo ) and
61+ model = ""
62+ or
63+ // models-as-data summarized flow
64+ FlowSummaryImpl:: Private:: Steps:: summaryLocalStep ( nodeFrom .( FlowSummaryNode ) .getSummaryNode ( ) ,
65+ nodeTo .( FlowSummaryNode ) .getSummaryNode ( ) , false , model )
66+ or
67+ // object->field conflation for content that is a `TaintInheritingContent`.
68+ exists ( DataFlow:: ContentSet f |
69+ readStep ( nodeFrom , f , nodeTo ) and
70+ f .getAReadContent ( ) instanceof TaintInheritingContent
71+ ) and
72+ model = ""
73+ }
6574}
6675
76+ import Cached
77+
6778/**
6879 * Holds if taint propagates from `nodeFrom` to `nodeTo` in exactly one local
6980 * (intra-procedural) step.
0 commit comments