Skip to content

Commit d0732a7

Browse files
committed
C#: Sync files.
1 parent eed8c72 commit d0732a7

File tree

1 file changed

+66
-56
lines changed

1 file changed

+66
-56
lines changed

csharp/ql/src/utils/modelgenerator/internal/CaptureModels.qll

Lines changed: 66 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,6 @@
55

66
private import CaptureModelsSpecific
77

8-
class ActiveConfiguration extends Unit {
9-
predicate activateThroughFlowConfig() { none() }
10-
11-
predicate activateFromSourceConfig() { none() }
12-
13-
predicate activateToSinkConfig() { none() }
14-
}
15-
168
class DataFlowTargetApi extends TargetApiSpecific {
179
DataFlowTargetApi() { isRelevantForDataFlowModels(this) }
1810
}
@@ -46,6 +38,20 @@ private predicate isRelevantContent(DataFlow::Content c) {
4638
DataFlowPrivate::containerContent(c)
4739
}
4840

41+
/**
42+
* Gets the MaD string representation of the parameter node `p`.
43+
*/
44+
string parameterNodeAsInput(DataFlow::ParameterNode p) {
45+
result = parameterAccess(p.asParameter())
46+
or
47+
result = qualifierString() and p instanceof InstanceParameterNode
48+
}
49+
50+
/**
51+
* Gets the MaD input string representation of `source`.
52+
*/
53+
string asInputArgument(DataFlow::Node source) { result = asInputArgumentSpecific(source) }
54+
4955
/**
5056
* Gets the summary model for `api` with `input`, `output` and `kind`.
5157
*/
@@ -111,61 +117,70 @@ string captureQualifierFlow(TargetApiSpecific api) {
111117

112118
private int accessPathLimit() { result = 2 }
113119

120+
private newtype TTaintState =
121+
TTaintRead(int n) { n in [0 .. accessPathLimit()] } or
122+
TTaintStore(int n) { n in [1 .. accessPathLimit()] }
123+
124+
abstract private class TaintState extends TTaintState {
125+
abstract string toString();
126+
}
127+
114128
/**
115129
* A FlowState representing a tainted read.
116130
*/
117-
private class TaintRead extends DataFlow::FlowState {
131+
private class TaintRead extends TaintState, TTaintRead {
118132
private int step;
119133

120-
TaintRead() { this = "TaintRead(" + step + ")" and step in [0 .. accessPathLimit()] }
134+
TaintRead() { this = TTaintRead(step) }
121135

122136
/**
123137
* Gets the flow state step number.
124138
*/
125139
int getStep() { result = step }
140+
141+
override string toString() { result = "TaintRead(" + step + ")" }
126142
}
127143

128144
/**
129145
* A FlowState representing a tainted write.
130146
*/
131-
private class TaintStore extends DataFlow::FlowState {
147+
private class TaintStore extends TaintState, TTaintStore {
132148
private int step;
133149

134-
TaintStore() { this = "TaintStore(" + step + ")" and step in [1 .. accessPathLimit()] }
150+
TaintStore() { this = TTaintStore(step) }
135151

136152
/**
137153
* Gets the flow state step number.
138154
*/
139155
int getStep() { result = step }
156+
157+
override string toString() { result = "TaintStore(" + step + ")" }
140158
}
141159

142160
/**
143-
* A TaintTracking Configuration used for tracking flow through APIs.
161+
* A data-flow configuration for tracking flow through APIs.
144162
* The sources are the parameters of an API and the sinks are the return values (excluding `this`) and parameters.
145163
*
146164
* This can be used to generate Flow summaries for APIs from parameter to return.
147165
*/
148-
private class ThroughFlowConfig extends TaintTracking::Configuration {
149-
ThroughFlowConfig() {
150-
this = "ThroughFlowConfig" and any(ActiveConfiguration ac).activateThroughFlowConfig()
151-
}
166+
module ThroughFlowConfig implements DataFlow::StateConfigSig {
167+
class FlowState = TaintState;
152168

153-
override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) {
169+
predicate isSource(DataFlow::Node source, FlowState state) {
154170
source instanceof DataFlow::ParameterNode and
155171
source.getEnclosingCallable() instanceof DataFlowTargetApi and
156172
state.(TaintRead).getStep() = 0
157173
}
158174

159-
override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) {
175+
predicate isSink(DataFlow::Node sink, FlowState state) {
160176
sink instanceof DataFlowImplCommon::ReturnNodeExt and
161177
not isOwnInstanceAccessNode(sink) and
162178
not exists(captureQualifierFlow(sink.asExpr().getEnclosingCallable())) and
163179
(state instanceof TaintRead or state instanceof TaintStore)
164180
}
165181

166-
override predicate isAdditionalTaintStep(
167-
DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2,
168-
DataFlow::FlowState state2
182+
predicate isAdditionalFlowStep(
183+
DataFlow::Node node1, FlowState state1, DataFlow::Node node2, FlowState state2
169184
) {
170185
exists(DataFlowImplCommon::TypedContent tc |
171186
DataFlowImplCommon::store(node1, tc, node2, _) and
@@ -184,24 +199,28 @@ private class ThroughFlowConfig extends TaintTracking::Configuration {
184199
)
185200
}
186201

187-
override predicate isSanitizer(DataFlow::Node n) {
202+
predicate isBarrier(DataFlow::Node n) {
188203
exists(Type t | t = n.getType() and not isRelevantType(t))
189204
}
190205

191-
override DataFlow::FlowFeature getAFeature() {
206+
predicate isBarrier(DataFlow::Node node, FlowState state) { none() }
207+
208+
DataFlow::FlowFeature getAFeature() {
192209
result instanceof DataFlow::FeatureEqualSourceSinkCallContext
193210
}
194211
}
195212

213+
private module ThroughFlow = TaintTracking::MakeWithState<ThroughFlowConfig>;
214+
196215
/**
197216
* Gets the summary model(s) of `api`, if there is flow from parameters to return value or parameter.
198217
*/
199218
string captureThroughFlow(DataFlowTargetApi api) {
200219
exists(
201-
ThroughFlowConfig config, DataFlow::ParameterNode p,
202-
DataFlowImplCommon::ReturnNodeExt returnNodeExt, string input, string output
220+
DataFlow::ParameterNode p, DataFlowImplCommon::ReturnNodeExt returnNodeExt, string input,
221+
string output
203222
|
204-
config.hasFlow(p, returnNodeExt) and
223+
ThroughFlow::hasFlow(p, returnNodeExt) and
205224
returnNodeExt.getEnclosingCallable() = api and
206225
input = parameterNodeAsInput(p) and
207226
output = returnNodeAsOutput(returnNodeExt) and
@@ -211,41 +230,37 @@ string captureThroughFlow(DataFlowTargetApi api) {
211230
}
212231

213232
/**
214-
* A TaintTracking Configuration used for tracking flow through APIs.
233+
* A dataflow configuration used for finding new sources.
215234
* The sources are the already known existing sources and the sinks are the API return nodes.
216235
*
217236
* This can be used to generate Source summaries for an API, if the API expose an already known source
218237
* via its return (then the API itself becomes a source).
219238
*/
220-
private class FromSourceConfiguration extends TaintTracking::Configuration {
221-
FromSourceConfiguration() {
222-
this = "FromSourceConfiguration" and any(ActiveConfiguration ac).activateFromSourceConfig()
223-
}
239+
module FromSourceConfig implements DataFlow::ConfigSig {
240+
predicate isSource(DataFlow::Node source) { ExternalFlow::sourceNode(source, _) }
224241

225-
override predicate isSource(DataFlow::Node source) { ExternalFlow::sourceNode(source, _) }
226-
227-
override predicate isSink(DataFlow::Node sink) {
242+
predicate isSink(DataFlow::Node sink) {
228243
exists(DataFlowTargetApi c |
229244
sink instanceof DataFlowImplCommon::ReturnNodeExt and
230245
sink.getEnclosingCallable() = c
231246
)
232247
}
233248

234-
override DataFlow::FlowFeature getAFeature() {
235-
result instanceof DataFlow::FeatureHasSinkCallContext
236-
}
249+
DataFlow::FlowFeature getAFeature() { result instanceof DataFlow::FeatureHasSinkCallContext }
237250

238-
override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
251+
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
239252
isRelevantTaintStep(node1, node2)
240253
}
241254
}
242255

256+
private module FromSource = TaintTracking::Make<FromSourceConfig>;
257+
243258
/**
244259
* Gets the source model(s) of `api`, if there is flow from an existing known source to the return of `api`.
245260
*/
246261
string captureSource(DataFlowTargetApi api) {
247-
exists(DataFlow::Node source, DataFlow::Node sink, FromSourceConfiguration config, string kind |
248-
config.hasFlow(source, sink) and
262+
exists(DataFlow::Node source, DataFlow::Node sink, string kind |
263+
FromSource::hasFlow(source, sink) and
249264
ExternalFlow::sourceNode(source, kind) and
250265
api = sink.getEnclosingCallable() and
251266
isRelevantSourceKind(kind) and
@@ -254,35 +269,30 @@ string captureSource(DataFlowTargetApi api) {
254269
}
255270

256271
/**
257-
* A TaintTracking Configuration used for tracking flow through APIs.
272+
* A dataflow configuration used for finding new sinks.
258273
* The sources are the parameters of the API and the fields of the enclosing type.
259274
*
260275
* This can be used to generate Sink summaries for APIs, if the API propagates a parameter (or enclosing type field)
261276
* into an existing known sink (then the API itself becomes a sink).
262277
*/
263-
private class PropagateToSinkConfiguration extends TaintTracking::Configuration {
264-
PropagateToSinkConfiguration() {
265-
this = "parameters or fields flowing into sinks" and
266-
any(ActiveConfiguration ac).activateToSinkConfig()
267-
}
278+
module PropagateToSinkConfig implements DataFlow::ConfigSig {
279+
predicate isSource(DataFlow::Node source) { apiSource(source) }
268280

269-
override predicate isSource(DataFlow::Node source) { apiSource(source) }
281+
predicate isSink(DataFlow::Node sink) { ExternalFlow::sinkNode(sink, _) }
270282

271-
override predicate isSink(DataFlow::Node sink) { ExternalFlow::sinkNode(sink, _) }
283+
predicate isBarrier(DataFlow::Node node) { sinkModelSanitizer(node) }
272284

273-
override predicate isSanitizer(DataFlow::Node node) { sinkModelSanitizer(node) }
274-
275-
override DataFlow::FlowFeature getAFeature() {
276-
result instanceof DataFlow::FeatureHasSourceCallContext
277-
}
285+
DataFlow::FlowFeature getAFeature() { result instanceof DataFlow::FeatureHasSourceCallContext }
278286
}
279287

288+
private module PropagateToSink = TaintTracking::Make<PropagateToSinkConfig>;
289+
280290
/**
281291
* Gets the sink model(s) of `api`, if there is flow from a parameter to an existing known sink.
282292
*/
283293
string captureSink(DataFlowTargetApi api) {
284-
exists(DataFlow::Node src, DataFlow::Node sink, PropagateToSinkConfiguration config, string kind |
285-
config.hasFlow(src, sink) and
294+
exists(DataFlow::Node src, DataFlow::Node sink, string kind |
295+
PropagateToSink::hasFlow(src, sink) and
286296
ExternalFlow::sinkNode(sink, kind) and
287297
api = src.getEnclosingCallable() and
288298
isRelevantSinkKind(kind) and

0 commit comments

Comments
 (0)