@@ -5,65 +5,77 @@ private import semmle.code.cpp.models.interfaces.DataFlow
55private import semmle.code.cpp.models.interfaces.SideEffect
66private import DataFlowUtil
77private import DataFlowPrivate
8+ private import DataFlowNodes
89private import SsaImpl as Ssa
910private import semmle.code.cpp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
1011private import semmle.code.cpp.ir.dataflow.FlowSteps
1112
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- */
3613cached
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 = ""
14+ private module Cached {
15+ private import DataFlowImplCommon as DataFlowImplCommon
16+
17+ cached
18+ predicate forceCachingInSameStage ( ) { DataFlowImplCommon:: forceCachingInSameStage ( ) }
19+
20+ /**
21+ * Holds if taint propagates from `nodeFrom` to `nodeTo` in exactly one local
22+ * (intra-procedural) step. This relation is only used for local taint flow
23+ * (for example `TaintTracking::localTaint(source, sink)`) so it may contain
24+ * special cases that should only apply to local taint flow.
25+ */
26+ cached
27+ predicate localTaintStep ( DataFlow:: Node nodeFrom , DataFlow:: Node nodeTo ) {
28+ // dataflow step
29+ DataFlow:: localFlowStep ( nodeFrom , nodeTo )
30+ or
31+ // taint flow step
32+ localAdditionalTaintStep ( nodeFrom , nodeTo , _)
33+ or
34+ // models-as-data summarized flow for local data flow (i.e. special case for flow
35+ // through calls to modeled functions, without relying on global dataflow to join
36+ // the dots).
37+ FlowSummaryImpl:: Private:: Steps:: summaryThroughStepTaint ( nodeFrom , nodeTo , _)
38+ }
39+
40+ /**
41+ * Holds if taint can flow in one local step from `nodeFrom` to `nodeTo` excluding
42+ * local data flow steps. That is, `nodeFrom` and `nodeTo` are likely to represent
43+ * different objects.
44+ */
45+ cached
46+ predicate localAdditionalTaintStep ( DataFlow:: Node nodeFrom , DataFlow:: Node nodeTo , string model ) {
47+ operandToInstructionTaintStep ( nodeFrom .asOperand ( ) , nodeTo .asInstruction ( ) ) and
48+ model = ""
49+ or
50+ modeledTaintStep ( nodeFrom , nodeTo , model )
51+ or
52+ // Flow from (the indirection of) an operand of a pointer arithmetic instruction to the
53+ // indirection of the pointer arithmetic instruction. This provides flow from `source`
54+ // in `x[source]` to the result of the associated load instruction.
55+ exists ( PointerArithmeticInstruction pai , int indirectionIndex |
56+ nodeHasOperand ( nodeFrom , pai .getAnOperand ( ) , pragma [ only_bind_into ] ( indirectionIndex ) ) and
57+ hasInstructionAndIndex ( nodeTo , pai , indirectionIndex + 1 )
58+ ) and
59+ model = ""
60+ or
61+ any ( Ssa:: Indirection ind ) .isAdditionalTaintStep ( nodeFrom , nodeTo ) and
62+ model = ""
63+ or
64+ // models-as-data summarized flow
65+ FlowSummaryImpl:: Private:: Steps:: summaryLocalStep ( nodeFrom .( FlowSummaryNode ) .getSummaryNode ( ) ,
66+ nodeTo .( FlowSummaryNode ) .getSummaryNode ( ) , false , model )
67+ or
68+ // object->field conflation for content that is a `TaintInheritingContent`.
69+ exists ( DataFlow:: ContentSet f |
70+ readStep ( nodeFrom , f , nodeTo ) and
71+ f .getAReadContent ( ) instanceof TaintInheritingContent
72+ ) and
73+ model = ""
74+ }
6575}
6676
77+ import Cached
78+
6779/**
6880 * Holds if taint propagates from `nodeFrom` to `nodeTo` in exactly one local
6981 * (intra-procedural) step.
@@ -196,7 +208,7 @@ predicate modeledTaintStep(DataFlow::Node nodeIn, DataFlow::Node nodeOut, string
196208 // Taint flow from a pointer argument to an output, when the model specifies flow from the deref
197209 // to that output, but the deref is not modeled in the IR for the caller.
198210 exists (
199- CallInstruction call , DataFlow :: SideEffectOperandNode indirectArgument , Function func ,
211+ CallInstruction call , SideEffectOperandNode indirectArgument , Function func ,
200212 FunctionInput modelIn , FunctionOutput modelOut
201213 |
202214 indirectArgument = callInput ( call , modelIn ) and
0 commit comments