Skip to content

Commit 00a273b

Browse files
committed
Java: Refactor data flow library.
1 parent a5bb336 commit 00a273b

16 files changed

+5180
-36811
lines changed

config/identical-files.json

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
{
22
"DataFlow Java/C++/C#/Go/Python/Ruby/Swift": [
3-
"java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll",
3+
"java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll"
4+
],
5+
"DataFlow Java/C++/C#/Go/Python/Ruby/Swift Legacy Configuration": [
6+
"java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl1.qll",
47
"java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll",
58
"java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll",
69
"java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll",
710
"java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll",
811
"java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll",
912
"java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForSerializability.qll",
10-
"java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForOnActivityResult.qll",
13+
"java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForOnActivityResult.qll"
14+
],
15+
"DataFlow Java/C++/C#/Go/Python/Ruby/Swift todo": [
1116
"cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll",
1217
"cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll",
1318
"cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll",
@@ -42,7 +47,9 @@
4247
"swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll"
4348
],
4449
"DataFlow Java/C++/C#/Go/Python/Ruby/Swift Common": [
45-
"java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll",
50+
"java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll"
51+
],
52+
"DataFlow Java/C++/C#/Go/Python/Ruby/Swift Common todo": [
4653
"cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll",
4754
"cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll",
4855
"cpp/ql/lib/experimental/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll",

java/ql/lib/semmle/code/java/dataflow/DataFlow.qll

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@
66
import java
77

88
module DataFlow {
9-
import semmle.code.java.dataflow.internal.DataFlowImpl
9+
import semmle.code.java.dataflow.internal.DataFlow
10+
import semmle.code.java.dataflow.internal.DataFlowImpl1
1011
}

java/ql/lib/semmle/code/java/dataflow/TaintTracking.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@ import semmle.code.java.dataflow.DataFlow2
88
import semmle.code.java.dataflow.internal.TaintTrackingUtil::StringBuilderVarModule
99

1010
module TaintTracking {
11+
import semmle.code.java.dataflow.internal.tainttracking1.TaintTracking
1112
import semmle.code.java.dataflow.internal.tainttracking1.TaintTrackingImpl
1213
}
Lines changed: 237 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
1+
/**
2+
* Provides an implementation of global (interprocedural) data flow. This file
3+
* re-exports the local (intraprocedural) data flow analysis from
4+
* `DataFlowImplSpecific::Public` and adds a global analysis, mainly exposed
5+
* through the `Make` and `MakeWithState` modules.
6+
*/
7+
8+
private import DataFlowImplCommon
9+
private import DataFlowImplSpecific::Private
10+
import DataFlowImplSpecific::Public
11+
import DataFlowImplCommonPublic
12+
private import DataFlowImpl
13+
14+
/** An input configuration for data flow. */
15+
signature module ConfigSig {
16+
/**
17+
* Holds if `source` is a relevant data flow source.
18+
*/
19+
predicate isSource(Node source);
20+
21+
/**
22+
* Holds if `sink` is a relevant data flow sink.
23+
*/
24+
predicate isSink(Node sink);
25+
26+
/**
27+
* Holds if data flow through `node` is prohibited. This completely removes
28+
* `node` from the data flow graph.
29+
*/
30+
default predicate isBarrier(Node node) { none() }
31+
32+
/** Holds if data flow into `node` is prohibited. */
33+
default predicate isBarrierIn(Node node) { none() }
34+
35+
/** Holds if data flow out of `node` is prohibited. */
36+
default predicate isBarrierOut(Node node) { none() }
37+
38+
/**
39+
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
40+
*/
41+
default predicate isAdditionalFlowStep(Node node1, Node node2) { none() }
42+
43+
/**
44+
* Holds if an arbitrary number of implicit read steps of content `c` may be
45+
* taken at `node`.
46+
*/
47+
default predicate allowImplicitRead(Node node, ContentSet c) { none() }
48+
49+
/**
50+
* Gets the virtual dispatch branching limit when calculating field flow.
51+
* This can be overridden to a smaller value to improve performance (a
52+
* value of 0 disables field flow), or a larger value to get more results.
53+
*/
54+
default int fieldFlowBranchLimit() { result = 2 }
55+
56+
/**
57+
* Gets a data flow configuration feature to add restrictions to the set of
58+
* valid flow paths.
59+
*
60+
* - `FeatureHasSourceCallContext`:
61+
* Assume that sources have some existing call context to disallow
62+
* conflicting return-flow directly following the source.
63+
* - `FeatureHasSinkCallContext`:
64+
* Assume that sinks have some existing call context to disallow
65+
* conflicting argument-to-parameter flow directly preceding the sink.
66+
* - `FeatureEqualSourceSinkCallContext`:
67+
* Implies both of the above and additionally ensures that the entire flow
68+
* path preserves the call context.
69+
*/
70+
default FlowFeature getAFeature() { none() }
71+
72+
/** Holds if sources should be grouped in the result of `hasFlowPath`. */
73+
default predicate sourceGrouping(Node source, string sourceGroup) { none() }
74+
75+
/** Holds if sinks should be grouped in the result of `hasFlowPath`. */
76+
default predicate sinkGrouping(Node sink, string sinkGroup) { none() }
77+
78+
/**
79+
* Holds if hidden nodes should be included in the data flow graph.
80+
*
81+
* This feature should only be used for debugging or when the data flow graph
82+
* is not visualized (as it is in a `path-problem` query).
83+
*/
84+
default predicate includeHiddenNodes() { none() }
85+
}
86+
87+
/** An input configuration for data flow using flow state. */
88+
signature module StateConfigSig {
89+
bindingset[this]
90+
class FlowState;
91+
92+
/**
93+
* Holds if `source` is a relevant data flow source with the given initial
94+
* `state`.
95+
*/
96+
predicate isSource(Node source, FlowState state);
97+
98+
/**
99+
* Holds if `sink` is a relevant data flow sink accepting `state`.
100+
*/
101+
predicate isSink(Node sink, FlowState state);
102+
103+
/**
104+
* Holds if data flow through `node` is prohibited. This completely removes
105+
* `node` from the data flow graph.
106+
*/
107+
default predicate isBarrier(Node node) { none() }
108+
109+
/**
110+
* Holds if data flow through `node` is prohibited when the flow state is
111+
* `state`.
112+
*/
113+
predicate isBarrier(Node node, FlowState state);
114+
115+
/** Holds if data flow into `node` is prohibited. */
116+
default predicate isBarrierIn(Node node) { none() }
117+
118+
/** Holds if data flow out of `node` is prohibited. */
119+
default predicate isBarrierOut(Node node) { none() }
120+
121+
/**
122+
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
123+
*/
124+
default predicate isAdditionalFlowStep(Node node1, Node node2) { none() }
125+
126+
/**
127+
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
128+
* This step is only applicable in `state1` and updates the flow state to `state2`.
129+
*/
130+
predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2);
131+
132+
/**
133+
* Holds if an arbitrary number of implicit read steps of content `c` may be
134+
* taken at `node`.
135+
*/
136+
default predicate allowImplicitRead(Node node, ContentSet c) { none() }
137+
138+
/**
139+
* Gets the virtual dispatch branching limit when calculating field flow.
140+
* This can be overridden to a smaller value to improve performance (a
141+
* value of 0 disables field flow), or a larger value to get more results.
142+
*/
143+
default int fieldFlowBranchLimit() { result = 2 }
144+
145+
/**
146+
* Gets a data flow configuration feature to add restrictions to the set of
147+
* valid flow paths.
148+
*
149+
* - `FeatureHasSourceCallContext`:
150+
* Assume that sources have some existing call context to disallow
151+
* conflicting return-flow directly following the source.
152+
* - `FeatureHasSinkCallContext`:
153+
* Assume that sinks have some existing call context to disallow
154+
* conflicting argument-to-parameter flow directly preceding the sink.
155+
* - `FeatureEqualSourceSinkCallContext`:
156+
* Implies both of the above and additionally ensures that the entire flow
157+
* path preserves the call context.
158+
*/
159+
default FlowFeature getAFeature() { none() }
160+
161+
/** Holds if sources should be grouped in the result of `hasFlowPath`. */
162+
default predicate sourceGrouping(Node source, string sourceGroup) { none() }
163+
164+
/** Holds if sinks should be grouped in the result of `hasFlowPath`. */
165+
default predicate sinkGrouping(Node sink, string sinkGroup) { none() }
166+
167+
/**
168+
* Holds if hidden nodes should be included in the data flow graph.
169+
*
170+
* This feature should only be used for debugging or when the data flow graph
171+
* is not visualized (as it is in a `path-problem` query).
172+
*/
173+
default predicate includeHiddenNodes() { none() }
174+
}
175+
176+
/**
177+
* Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev`
178+
* measured in approximate number of interprocedural steps.
179+
*/
180+
signature int explorationLimitSig();
181+
182+
/**
183+
* The output of a data flow computation.
184+
*/
185+
signature module DataFlowSig {
186+
/**
187+
* A `Node` augmented with a call context (except for sinks) and an access path.
188+
* Only those `PathNode`s that are reachable from a source, and which can reach a sink, are generated.
189+
*/
190+
class PathNode;
191+
192+
/**
193+
* Holds if data can flow from `source` to `sink`.
194+
*
195+
* The corresponding paths are generated from the end-points and the graph
196+
* included in the module `PathGraph`.
197+
*/
198+
predicate hasFlowPath(PathNode source, PathNode sink);
199+
200+
/**
201+
* Holds if data can flow from `source` to `sink`.
202+
*/
203+
predicate hasFlow(Node source, Node sink);
204+
205+
/**
206+
* Holds if data can flow from some source to `sink`.
207+
*/
208+
predicate hasFlowTo(Node sink);
209+
210+
/**
211+
* Holds if data can flow from some source to `sink`.
212+
*/
213+
predicate hasFlowToExpr(DataFlowExpr sink);
214+
}
215+
216+
/**
217+
* Constructs a standard data flow computation.
218+
*/
219+
module Make<ConfigSig Config> implements DataFlowSig {
220+
private module C implements FullStateConfigSig {
221+
import DefaultState<Config>
222+
import Config
223+
}
224+
225+
import Impl<C>
226+
}
227+
228+
/**
229+
* Constructs a data flow computation using flow state.
230+
*/
231+
module MakeWithState<StateConfigSig Config> implements DataFlowSig {
232+
private module C implements FullStateConfigSig {
233+
import Config
234+
}
235+
236+
import Impl<C>
237+
}

0 commit comments

Comments
 (0)