Skip to content

Commit 2925e45

Browse files
committed
Java/Dataflow: Propagate MaD-id/model-id to PathGraph.
1 parent 1015ee9 commit 2925e45

31 files changed

+680
-423
lines changed

java/ql/automodel/src/AutomodelAlertSinkUtil.qll

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ private newtype TSinkModel =
1515
string package, string type, boolean subtypes, string name, string signature, string ext,
1616
string input, string kind, string provenance
1717
) {
18-
ExternalFlow::sinkModel(package, type, subtypes, name, signature, ext, input, kind, provenance)
18+
ExternalFlow::sinkModel(package, type, subtypes, name, signature, ext, input, kind, provenance,
19+
_)
1920
}
2021

2122
class SinkModel extends TSinkModel {

java/ql/automodel/src/AutomodelApplicationModeCharacteristics.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ module ApplicationCandidatesImpl implements SharedCharacteristics::CandidateSig
259259
|
260260
sinkSpec(e, package, type, subtypes, name, signature, ext, input) and
261261
ExternalFlow::sinkModel(package, type, subtypes, name, [signature, ""], ext, input, kind,
262-
provenance)
262+
provenance, _)
263263
)
264264
or
265265
isCustomSink(e, kind) and provenance = "custom-sink"
@@ -272,7 +272,7 @@ module ApplicationCandidatesImpl implements SharedCharacteristics::CandidateSig
272272
|
273273
sourceSpec(e, package, type, subtypes, name, signature, ext, output) and
274274
ExternalFlow::sourceModel(package, type, subtypes, name, [signature, ""], ext, output, kind,
275-
provenance)
275+
provenance, _)
276276
)
277277
}
278278

java/ql/automodel/src/AutomodelFrameworkModeCharacteristics.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ module FrameworkCandidatesImpl implements SharedCharacteristics::CandidateSig {
215215
|
216216
sinkSpec(e, package, type, subtypes, name, signature, ext, input) and
217217
ExternalFlow::sinkModel(package, type, subtypes, name, [signature, ""], ext, input, kind,
218-
provenance)
218+
provenance, _)
219219
)
220220
}
221221

@@ -226,7 +226,7 @@ module FrameworkCandidatesImpl implements SharedCharacteristics::CandidateSig {
226226
|
227227
sourceSpec(e, package, type, subtypes, name, signature, ext, output) and
228228
ExternalFlow::sourceModel(package, type, subtypes, name, [signature, ""], ext, output, kind,
229-
provenance)
229+
provenance, _)
230230
)
231231
}
232232

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

Lines changed: 87 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -113,76 +113,85 @@ abstract class ActiveExperimentalModels extends string {
113113
*/
114114
predicate sourceModel(
115115
string package, string type, boolean subtypes, string name, string signature, string ext,
116-
string output, string kind, string provenance
116+
string output, string kind, string provenance, QlBuiltins::ExtensionId madId
117117
) {
118118
Extensions::experimentalSourceModel(package, type, subtypes, name, signature, ext, output, kind,
119-
provenance, this)
119+
provenance, this, madId)
120120
}
121121

122122
/**
123123
* Holds if an experimental sink model exists for the given parameters.
124124
*/
125125
predicate sinkModel(
126126
string package, string type, boolean subtypes, string name, string signature, string ext,
127-
string output, string kind, string provenance
127+
string output, string kind, string provenance, QlBuiltins::ExtensionId madId
128128
) {
129129
Extensions::experimentalSinkModel(package, type, subtypes, name, signature, ext, output, kind,
130-
provenance, this)
130+
provenance, this, madId)
131131
}
132132

133133
/**
134134
* Holds if an experimental summary model exists for the given parameters.
135135
*/
136136
predicate summaryModel(
137137
string package, string type, boolean subtypes, string name, string signature, string ext,
138-
string input, string output, string kind, string provenance
138+
string input, string output, string kind, string provenance, QlBuiltins::ExtensionId madId
139139
) {
140140
Extensions::experimentalSummaryModel(package, type, subtypes, name, signature, ext, input,
141-
output, kind, provenance, this)
141+
output, kind, provenance, this, madId)
142142
}
143143
}
144144

145145
/** Holds if a source model exists for the given parameters. */
146146
predicate sourceModel(
147147
string package, string type, boolean subtypes, string name, string signature, string ext,
148-
string output, string kind, string provenance
148+
string output, string kind, string provenance, QlBuiltins::ExtensionId madId
149149
) {
150-
Extensions::sourceModel(package, type, subtypes, name, signature, ext, output, kind, provenance)
151-
or
152-
any(ActiveExperimentalModels q)
153-
.sourceModel(package, type, subtypes, name, signature, ext, output, kind, provenance)
150+
(
151+
Extensions::sourceModel(package, type, subtypes, name, signature, ext, output, kind, provenance,
152+
madId)
153+
or
154+
any(ActiveExperimentalModels q)
155+
.sourceModel(package, type, subtypes, name, signature, ext, output, kind, provenance, madId)
156+
)
154157
}
155158

156159
/** Holds if a sink model exists for the given parameters. */
157160
predicate sinkModel(
158161
string package, string type, boolean subtypes, string name, string signature, string ext,
159-
string input, string kind, string provenance
162+
string input, string kind, string provenance, QlBuiltins::ExtensionId madId
160163
) {
161-
Extensions::sinkModel(package, type, subtypes, name, signature, ext, input, kind, provenance)
162-
or
163-
any(ActiveExperimentalModels q)
164-
.sinkModel(package, type, subtypes, name, signature, ext, input, kind, provenance)
164+
(
165+
Extensions::sinkModel(package, type, subtypes, name, signature, ext, input, kind, provenance,
166+
madId)
167+
or
168+
any(ActiveExperimentalModels q)
169+
.sinkModel(package, type, subtypes, name, signature, ext, input, kind, provenance, madId)
170+
)
165171
}
166172

167173
/** Holds if a summary model exists for the given parameters. */
168174
predicate summaryModel(
169175
string package, string type, boolean subtypes, string name, string signature, string ext,
170-
string input, string output, string kind, string provenance
176+
string input, string output, string kind, string provenance, QlBuiltins::ExtensionId madId
171177
) {
172-
Extensions::summaryModel(package, type, subtypes, name, signature, ext, input, output, kind,
173-
provenance)
174-
or
175-
any(ActiveExperimentalModels q)
176-
.summaryModel(package, type, subtypes, name, signature, ext, input, output, kind, provenance)
178+
(
179+
Extensions::summaryModel(package, type, subtypes, name, signature, ext, input, output, kind,
180+
provenance, madId)
181+
or
182+
any(ActiveExperimentalModels q)
183+
.summaryModel(package, type, subtypes, name, signature, ext, input, output, kind,
184+
provenance, madId)
185+
)
177186
}
178187

179188
/** Holds if a neutral model exists for the given parameters. */
180189
predicate neutralModel = Extensions::neutralModel/6;
181190

182191
private predicate relevantPackage(string package) {
183-
sourceModel(package, _, _, _, _, _, _, _, _) or
184-
sinkModel(package, _, _, _, _, _, _, _, _) or
185-
summaryModel(package, _, _, _, _, _, _, _, _, _)
192+
sourceModel(package, _, _, _, _, _, _, _, _, _) or
193+
sinkModel(package, _, _, _, _, _, _, _, _, _) or
194+
summaryModel(package, _, _, _, _, _, _, _, _, _, _)
186195
}
187196

188197
private predicate packageLink(string shortpkg, string longpkg) {
@@ -212,23 +221,24 @@ predicate modelCoverage(string package, int pkgs, string kind, string part, int
212221
strictcount(string subpkg, string type, boolean subtypes, string name, string signature,
213222
string ext, string output, string provenance |
214223
canonicalPkgLink(package, subpkg) and
215-
sourceModel(subpkg, type, subtypes, name, signature, ext, output, kind, provenance)
224+
sourceModel(subpkg, type, subtypes, name, signature, ext, output, kind, provenance, _)
216225
)
217226
or
218227
part = "sink" and
219228
n =
220229
strictcount(string subpkg, string type, boolean subtypes, string name, string signature,
221230
string ext, string input, string provenance |
222231
canonicalPkgLink(package, subpkg) and
223-
sinkModel(subpkg, type, subtypes, name, signature, ext, input, kind, provenance)
232+
sinkModel(subpkg, type, subtypes, name, signature, ext, input, kind, provenance, _)
224233
)
225234
or
226235
part = "summary" and
227236
n =
228237
strictcount(string subpkg, string type, boolean subtypes, string name, string signature,
229238
string ext, string input, string output, string provenance |
230239
canonicalPkgLink(package, subpkg) and
231-
summaryModel(subpkg, type, subtypes, name, signature, ext, input, output, kind, provenance)
240+
summaryModel(subpkg, type, subtypes, name, signature, ext, input, output, kind, provenance,
241+
_)
232242
)
233243
)
234244
}
@@ -238,10 +248,10 @@ module ModelValidation {
238248
private import codeql.dataflow.internal.AccessPathSyntax as AccessPathSyntax
239249

240250
private predicate getRelevantAccessPath(string path) {
241-
summaryModel(_, _, _, _, _, _, path, _, _, _) or
242-
summaryModel(_, _, _, _, _, _, _, path, _, _) or
243-
sinkModel(_, _, _, _, _, _, path, _, _) or
244-
sourceModel(_, _, _, _, _, _, path, _, _)
251+
summaryModel(_, _, _, _, _, _, path, _, _, _, _) or
252+
summaryModel(_, _, _, _, _, _, _, path, _, _, _) or
253+
sinkModel(_, _, _, _, _, _, path, _, _, _) or
254+
sourceModel(_, _, _, _, _, _, path, _, _, _)
245255
}
246256

247257
private module MkAccessPath = AccessPathSyntax::AccessPath<getRelevantAccessPath/1>;
@@ -252,9 +262,9 @@ module ModelValidation {
252262

253263
private string getInvalidModelInput() {
254264
exists(string pred, AccessPath input, AccessPathToken part |
255-
sinkModel(_, _, _, _, _, _, input, _, _) and pred = "sink"
265+
sinkModel(_, _, _, _, _, _, input, _, _, _) and pred = "sink"
256266
or
257-
summaryModel(_, _, _, _, _, _, input, _, _, _) and pred = "summary"
267+
summaryModel(_, _, _, _, _, _, input, _, _, _, _) and pred = "summary"
258268
|
259269
(
260270
invalidSpecComponent(input, part) and
@@ -274,9 +284,9 @@ module ModelValidation {
274284

275285
private string getInvalidModelOutput() {
276286
exists(string pred, AccessPath output, AccessPathToken part |
277-
sourceModel(_, _, _, _, _, _, output, _, _) and pred = "source"
287+
sourceModel(_, _, _, _, _, _, output, _, _, _) and pred = "source"
278288
or
279-
summaryModel(_, _, _, _, _, _, _, output, _, _) and pred = "summary"
289+
summaryModel(_, _, _, _, _, _, _, output, _, _, _) and pred = "summary"
280290
|
281291
(
282292
invalidSpecComponent(output, part) and
@@ -291,11 +301,11 @@ module ModelValidation {
291301
}
292302

293303
private module KindValConfig implements SharedModelVal::KindValidationConfigSig {
294-
predicate summaryKind(string kind) { summaryModel(_, _, _, _, _, _, _, _, kind, _) }
304+
predicate summaryKind(string kind) { summaryModel(_, _, _, _, _, _, _, _, kind, _, _) }
295305

296-
predicate sinkKind(string kind) { sinkModel(_, _, _, _, _, _, _, kind, _) }
306+
predicate sinkKind(string kind) { sinkModel(_, _, _, _, _, _, _, kind, _, _) }
297307

298-
predicate sourceKind(string kind) { sourceModel(_, _, _, _, _, _, _, kind, _) }
308+
predicate sourceKind(string kind) { sourceModel(_, _, _, _, _, _, _, kind, _, _) }
299309

300310
predicate neutralKind(string kind) { neutralModel(_, _, _, _, kind, _) }
301311
}
@@ -307,11 +317,11 @@ module ModelValidation {
307317
string pred, string package, string type, string name, string signature, string ext,
308318
string provenance
309319
|
310-
sourceModel(package, type, _, name, signature, ext, _, _, provenance) and pred = "source"
320+
sourceModel(package, type, _, name, signature, ext, _, _, provenance, _) and pred = "source"
311321
or
312-
sinkModel(package, type, _, name, signature, ext, _, _, provenance) and pred = "sink"
322+
sinkModel(package, type, _, name, signature, ext, _, _, provenance, _) and pred = "sink"
313323
or
314-
summaryModel(package, type, _, name, signature, ext, _, _, _, provenance) and
324+
summaryModel(package, type, _, name, signature, ext, _, _, _, provenance, _) and
315325
pred = "summary"
316326
or
317327
neutralModel(package, type, name, signature, _, provenance) and
@@ -352,11 +362,11 @@ pragma[nomagic]
352362
private predicate elementSpec(
353363
string package, string type, boolean subtypes, string name, string signature, string ext
354364
) {
355-
sourceModel(package, type, subtypes, name, signature, ext, _, _, _)
365+
sourceModel(package, type, subtypes, name, signature, ext, _, _, _, _)
356366
or
357-
sinkModel(package, type, subtypes, name, signature, ext, _, _, _)
367+
sinkModel(package, type, subtypes, name, signature, ext, _, _, _, _)
358368
or
359-
summaryModel(package, type, subtypes, name, signature, ext, _, _, _, _)
369+
summaryModel(package, type, subtypes, name, signature, ext, _, _, _, _, _)
360370
or
361371
neutralModel(package, type, name, signature, _, _) and ext = "" and subtypes = false
362372
}
@@ -494,9 +504,9 @@ private module Cached {
494504
* model.
495505
*/
496506
cached
497-
predicate sourceNode(Node node, string kind) {
507+
predicate sourceNode(Node node, string kind, string model) {
498508
exists(SourceSinkInterpretationInput::InterpretNode n |
499-
isSourceNode(n, kind) and n.asNode() = node
509+
isSourceNode(n, kind, model) and n.asNode() = node
500510
)
501511
}
502512

@@ -505,29 +515,45 @@ private module Cached {
505515
* model.
506516
*/
507517
cached
508-
predicate sinkNode(Node node, string kind) {
518+
predicate sinkNode(Node node, string kind, string model) {
509519
exists(SourceSinkInterpretationInput::InterpretNode n |
510-
isSinkNode(n, kind) and n.asNode() = node
520+
isSinkNode(n, kind, model) and n.asNode() = node
511521
)
512522
}
513523
}
514524

515525
import Cached
516526

527+
/**
528+
* Holds if `node` is specified as a source with the given kind in a MaD flow
529+
* model.
530+
*/
531+
predicate sourceNode(Node node, string kind) { sourceNode(node, kind, _) }
532+
533+
/**
534+
* Holds if `node` is specified as a sink with the given kind in a MaD flow
535+
* model.
536+
*/
537+
predicate sinkNode(Node node, string kind) { sinkNode(node, kind, _) }
538+
517539
// adapter class for converting Mad summaries to `SummarizedCallable`s
518540
private class SummarizedCallableAdapter extends SummarizedCallable {
519-
SummarizedCallableAdapter() { summaryElement(this, _, _, _, _) }
541+
SummarizedCallableAdapter() { summaryElement(this, _, _, _, _, _) }
520542

521-
private predicate relevantSummaryElementManual(string input, string output, string kind) {
543+
private predicate relevantSummaryElementManual(
544+
string input, string output, string kind, string model
545+
) {
522546
exists(Provenance provenance |
523-
summaryElement(this, input, output, kind, provenance) and
547+
summaryElement(this, input, output, kind, provenance, model) and
524548
provenance.isManual()
525549
)
526550
}
527551

528-
private predicate relevantSummaryElementGenerated(string input, string output, string kind) {
552+
private predicate relevantSummaryElementGenerated(
553+
string input, string output, string kind, string model
554+
) {
529555
exists(Provenance provenance |
530-
summaryElement(this, input, output, kind, provenance) and
556+
summaryElement(this, input, output, kind, provenance, model) and
531557
provenance.isGenerated()
532558
) and
533559
not exists(Provenance provenance |
@@ -536,19 +562,21 @@ private class SummarizedCallableAdapter extends SummarizedCallable {
536562
)
537563
}
538564

539-
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
565+
override predicate propagatesFlow(
566+
string input, string output, boolean preservesValue, string model
567+
) {
540568
exists(string kind |
541-
this.relevantSummaryElementManual(input, output, kind)
569+
this.relevantSummaryElementManual(input, output, kind, model)
542570
or
543-
not this.relevantSummaryElementManual(_, _, _) and
544-
this.relevantSummaryElementGenerated(input, output, kind)
571+
not this.relevantSummaryElementManual(_, _, _, _) and
572+
this.relevantSummaryElementGenerated(input, output, kind, model)
545573
|
546574
if kind = "value" then preservesValue = true else preservesValue = false
547575
)
548576
}
549577

550578
override predicate hasProvenance(Provenance provenance) {
551-
summaryElement(this, _, _, _, provenance)
579+
summaryElement(this, _, _, _, provenance, _)
552580
}
553581
}
554582

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,14 @@ class SummarizedCallable = Impl::Public::SummarizedCallable;
126126
* to `SummarizedCallable`.
127127
*/
128128
private class SummarizedSyntheticCallableAdapter extends SummarizedCallable, TSyntheticCallable {
129-
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
130-
this.asSyntheticCallable().propagatesFlow(input, output, preservesValue)
129+
override predicate propagatesFlow(
130+
string input, string output, boolean preservesValue, string model
131+
) {
132+
exists(SyntheticCallable sc |
133+
sc = this.asSyntheticCallable() and
134+
sc.propagatesFlow(input, output, preservesValue) and
135+
model = sc
136+
)
131137
}
132138
}
133139

java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl1.qll

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -263,9 +263,10 @@ deprecated private module Config implements FullStateConfigSig {
263263

264264
predicate isBarrierOut(Node node, FlowState state) { none() }
265265

266-
predicate isAdditionalFlowStep(Node node1, Node node2) {
266+
predicate isAdditionalFlowStep(Node node1, Node node2, string model) {
267267
singleConfiguration() and
268-
any(Configuration config).isAdditionalFlowStep(node1, node2)
268+
any(Configuration config).isAdditionalFlowStep(node1, node2) and
269+
model = ""
269270
}
270271

271272
predicate isAdditionalFlowStep(Node node1, FlowState state1, Node node2, FlowState state2) {

0 commit comments

Comments
 (0)