Skip to content

Commit 5f1a176

Browse files
committed
Java: Sync CaptureModels implementation to only allow at most two reads and two stores.
1 parent a488d6b commit 5f1a176

File tree

1 file changed

+35
-7
lines changed

1 file changed

+35
-7
lines changed

java/ql/src/utils/model-generator/internal/CaptureModels.qll

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -90,33 +90,59 @@ string captureQualifierFlow(TargetApi api) {
9090
result = asValueModel(api, qualifierString(), "ReturnValue")
9191
}
9292

93+
private int accessPathLimit() { result = 2 }
94+
9395
/**
9496
* A FlowState representing a tainted read.
9597
*/
9698
private class TaintRead extends DataFlow::FlowState {
97-
TaintRead() { this = "TaintRead" }
99+
private int step;
100+
101+
TaintRead() { this = "TaintRead(" + step + ")" and step in [0 .. accessPathLimit()] }
102+
103+
/**
104+
* Gets the flow state step number.
105+
*/
106+
int getStep() { result = step }
98107
}
99108

100109
/**
101110
* A FlowState representing a tainted write.
102111
*/
103112
private class TaintStore extends DataFlow::FlowState {
104-
TaintStore() { this = "TaintStore" }
113+
private int step;
114+
115+
TaintStore() { this = "TaintStore(" + step + ")" and step in [1 .. accessPathLimit()] }
116+
117+
/**
118+
* Gets the flow state step number.
119+
*/
120+
int getStep() { result = step }
105121
}
106122

107123
/**
108124
* A TaintTracking Configuration used for tracking flow through APIs.
109125
* The sources are the parameters of an API and the sinks are the return values (excluding `this`) and parameters.
110126
*
111127
* This can be used to generate Flow summaries for APIs from parameter to return.
128+
*
129+
* * We track at most two reads and at most two stores, meaning flow paths of the form
130+
*
131+
* ```
132+
* parameter --value -->* node --read -->?
133+
* node --taint -->* node --read -->?
134+
* node --taint -->* node --store -->?
135+
* node --taint -->* node --store -->?
136+
* node --taint-->* return
137+
* ```
112138
*/
113139
private class ThroughFlowConfig extends TaintTracking::Configuration {
114140
ThroughFlowConfig() { this = "ThroughFlowConfig" }
115141

116142
override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) {
117143
source instanceof DataFlow::ParameterNode and
118144
source.getEnclosingCallable() instanceof TargetApi and
119-
state instanceof TaintRead
145+
state.(TaintRead).getStep() = 0
120146
}
121147

122148
override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) {
@@ -133,15 +159,17 @@ private class ThroughFlowConfig extends TaintTracking::Configuration {
133159
exists(DataFlowImplCommon::TypedContent tc |
134160
DataFlowImplCommon::store(node1, tc, node2, _) and
135161
isRelevantContent(tc.getContent()) and
136-
(state1 instanceof TaintRead or state1 instanceof TaintStore) and
137-
state2 instanceof TaintStore
162+
(
163+
state1 instanceof TaintRead and state2.(TaintStore).getStep() = 1
164+
or
165+
state1.(TaintStore).getStep() + 1 = state2.(TaintStore).getStep()
166+
)
138167
)
139168
or
140169
exists(DataFlow::Content c |
141170
DataFlowPrivate::readStep(node1, c, node2) and
142171
isRelevantContent(c) and
143-
state1 instanceof TaintRead and
144-
state2 instanceof TaintRead
172+
state1.(TaintRead).getStep() + 1 = state2.(TaintRead).getStep()
145173
)
146174
}
147175

0 commit comments

Comments
 (0)