Skip to content

Commit 15e467d

Browse files
committed
Java: Basic support for pass-through barrier models.
1 parent 000f2c3 commit 15e467d

File tree

5 files changed

+104
-6
lines changed

5 files changed

+104
-6
lines changed

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

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,15 @@ predicate sinkModel(
174174
)
175175
}
176176

177+
/** Holds if a barrier model exists for the given parameters. */
178+
predicate barrierModel(
179+
string package, string type, boolean subtypes, string name, string signature, string ext,
180+
string output, string kind, string provenance, QlBuiltins::ExtensionId madId
181+
) {
182+
Extensions::barrierModel(package, type, subtypes, name, signature, ext, output, kind, provenance,
183+
madId)
184+
}
185+
177186
/** Holds if a summary model exists for the given parameters. */
178187
predicate summaryModel(
179188
string package, string type, boolean subtypes, string name, string signature, string ext,
@@ -234,6 +243,7 @@ predicate interpretModelForTest(QlBuiltins::ExtensionId madId, string model) {
234243
"Summary: " + package + "; " + type + "; " + subtypes + "; " + name + "; " + signature + "; " +
235244
ext + "; " + input + "; " + output + "; " + kind + "; " + provenance
236245
)
246+
//TODO: possibly barrier models?
237247
}
238248

239249
/** Holds if a neutral model exists for the given parameters. */
@@ -292,6 +302,7 @@ predicate modelCoverage(string package, int pkgs, string kind, string part, int
292302
summaryModel(subpkg, type, subtypes, name, signature, ext, input, output, kind, provenance,
293303
_)
294304
)
305+
// TODO: possibly barrier models?
295306
)
296307
}
297308

@@ -303,7 +314,8 @@ module ModelValidation {
303314
summaryModel(_, _, _, _, _, _, path, _, _, _, _) or
304315
summaryModel(_, _, _, _, _, _, _, path, _, _, _) or
305316
sinkModel(_, _, _, _, _, _, path, _, _, _) or
306-
sourceModel(_, _, _, _, _, _, path, _, _, _)
317+
sourceModel(_, _, _, _, _, _, path, _, _, _) or
318+
barrierModel(_, _, _, _, _, _, path, _, _, _)
307319
}
308320

309321
private module MkAccessPath = AccessPathSyntax::AccessPath<getRelevantAccessPath/1>;
@@ -338,6 +350,8 @@ module ModelValidation {
338350
exists(string pred, AccessPath output, AccessPathToken part |
339351
sourceModel(_, _, _, _, _, _, output, _, _, _) and pred = "source"
340352
or
353+
barrierModel(_, _, _, _, _, _, output, _, _, _) and pred = "barrier"
354+
or
341355
summaryModel(_, _, _, _, _, _, _, output, _, _, _) and pred = "summary"
342356
|
343357
(
@@ -355,7 +369,11 @@ module ModelValidation {
355369
private module KindValConfig implements SharedModelVal::KindValidationConfigSig {
356370
predicate summaryKind(string kind) { summaryModel(_, _, _, _, _, _, _, _, kind, _, _) }
357371

358-
predicate sinkKind(string kind) { sinkModel(_, _, _, _, _, _, _, kind, _, _) }
372+
predicate sinkKind(string kind) {
373+
sinkModel(_, _, _, _, _, _, _, kind, _, _)
374+
or
375+
barrierModel(_, _, _, _, _, _, _, kind, _, _)
376+
}
359377

360378
predicate sourceKind(string kind) { sourceModel(_, _, _, _, _, _, _, kind, _, _) }
361379

@@ -373,6 +391,8 @@ module ModelValidation {
373391
or
374392
sinkModel(package, type, _, name, signature, ext, _, _, provenance, _) and pred = "sink"
375393
or
394+
barrierModel(package, type, _, name, signature, ext, _, _, provenance, _) and pred = "barrier"
395+
or
376396
summaryModel(package, type, _, name, signature, ext, _, _, _, provenance, _) and
377397
pred = "summary"
378398
or
@@ -418,6 +438,8 @@ private predicate elementSpec(
418438
or
419439
sinkModel(package, type, subtypes, name, signature, ext, _, _, _, _)
420440
or
441+
barrierModel(package, type, subtypes, name, signature, ext, _, _, _, _)
442+
or
421443
summaryModel(package, type, subtypes, name, signature, ext, _, _, _, _, _)
422444
or
423445
neutralModel(package, type, name, signature, _, _) and ext = "" and subtypes = true
@@ -578,6 +600,17 @@ private module Cached {
578600
isSinkNode(n, kind, model) and n.asNode() = node
579601
)
580602
}
603+
604+
/**
605+
* Holds if `node` is specified as a barrier with the given kind in a MaD flow
606+
* model.
607+
*/
608+
cached
609+
predicate barrierNode(Node node, string kind, string model) {
610+
exists(SourceSinkInterpretationInput::InterpretNode n |
611+
isBarrierNode(n, kind, model) and n.asNode() = node
612+
)
613+
}
581614
}
582615

583616
import Cached
@@ -594,6 +627,12 @@ predicate sourceNode(Node node, string kind) { sourceNode(node, kind, _) }
594627
*/
595628
predicate sinkNode(Node node, string kind) { sinkNode(node, kind, _) }
596629

630+
/**
631+
* Holds if `node` is specified as a barrier with the given kind in a MaD flow
632+
* model.
633+
*/
634+
predicate barrierNode(Node node, string kind) { barrierNode(node, kind, _) }
635+
597636
// adapter class for converting Mad summaries to `SummarizedCallable`s
598637
private class SummarizedCallableAdapter extends SummarizedCallable {
599638
SummarizedCallableAdapter() { summaryElement(this, _, _, _, _, _, _) }

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@ extensible predicate sinkModel(
2020
string input, string kind, string provenance, QlBuiltins::ExtensionId madId
2121
);
2222

23+
/**
24+
* Holds if a barrier model exists for the given parameters.
25+
*/
26+
extensible predicate barrierModel(
27+
string package, string type, boolean subtypes, string name, string signature, string ext,
28+
string output, string kind, string provenance, QlBuiltins::ExtensionId madId
29+
);
30+
2331
/**
2432
* Holds if a summary model exists for the given parameters.
2533
*/

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

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,8 @@ private predicate relatedArgSpec(Callable c, string spec) {
158158
summaryModel(namespace, type, subtypes, name, signature, ext, spec, _, _, _, _) or
159159
summaryModel(namespace, type, subtypes, name, signature, ext, _, spec, _, _, _) or
160160
sourceModel(namespace, type, subtypes, name, signature, ext, spec, _, _, _) or
161-
sinkModel(namespace, type, subtypes, name, signature, ext, spec, _, _, _)
161+
sinkModel(namespace, type, subtypes, name, signature, ext, spec, _, _, _) or
162+
barrierModel(namespace, type, subtypes, name, signature, ext, spec, _, _, _)
162163
|
163164
c = interpretElement(namespace, type, subtypes, name, signature, ext, _)
164165
)
@@ -259,6 +260,25 @@ module SourceSinkInterpretationInput implements
259260
)
260261
}
261262

263+
predicate barrierElement(
264+
Element e, string output, string kind, Public::Provenance provenance, string model
265+
) {
266+
exists(
267+
string namespace, string type, boolean subtypes, string name, string signature, string ext,
268+
SourceOrSinkElement baseBarrier, string originalOutput, QlBuiltins::ExtensionId madId
269+
|
270+
barrierModel(namespace, type, subtypes, name, signature, ext, originalOutput, kind, provenance,
271+
madId) and
272+
model = "MaD:" + madId.toString() and
273+
baseBarrier = interpretElement(namespace, type, subtypes, name, signature, ext, _) and
274+
(
275+
e = baseBarrier and output = originalOutput
276+
or
277+
correspondingKotlinParameterDefaultsArgSpec(baseBarrier, e, originalOutput, output)
278+
)
279+
)
280+
}
281+
262282
class SourceOrSinkElement = Element;
263283

264284
private newtype TInterpretNode =

shared/dataflow/codeql/dataflow/internal/FlowSummaryImpl.qll

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2052,6 +2052,14 @@ module Make<
20522052
Element n, string input, string kind, Provenance provenance, string model
20532053
);
20542054

2055+
/**
2056+
* Holds if an external barrier specification exists for `n` with output specification
2057+
* `output` and kind `kind`.
2058+
*/
2059+
predicate barrierElement(
2060+
Element n, string output, string kind, Provenance provenance, string model
2061+
);
2062+
20552063
class SourceOrSinkElement extends Element;
20562064

20572065
/** An entity used to interpret a source/sink specification. */
@@ -2105,7 +2113,8 @@ module Make<
21052113

21062114
private predicate sourceSinkSpec(string spec) {
21072115
sourceElement(_, spec, _, _, _) or
2108-
sinkElement(_, spec, _, _, _)
2116+
sinkElement(_, spec, _, _, _) or
2117+
barrierElement(_, spec, _, _, _)
21092118
}
21102119

21112120
private module AccessPath = AccessPathSyntax::AccessPath<sourceSinkSpec/1>;
@@ -2160,11 +2169,22 @@ module Make<
21602169
)
21612170
}
21622171

2172+
private predicate barrierElementRef(
2173+
InterpretNode ref, SourceSinkAccessPath output, string kind, string model
2174+
) {
2175+
exists(SourceOrSinkElement e |
2176+
barrierElement(e, output, kind, _, model) and
2177+
if outputNeedsReferenceExt(output.getToken(0))
2178+
then e = ref.getCallTarget()
2179+
else e = ref.asElement()
2180+
)
2181+
}
2182+
21632183
/** Holds if the first `n` tokens of `output` resolve to the given interpretation. */
21642184
private predicate interpretOutput(
21652185
SourceSinkAccessPath output, int n, InterpretNode ref, InterpretNode node
21662186
) {
2167-
sourceElementRef(ref, output, _, _) and
2187+
(sourceElementRef(ref, output, _, _) or barrierElementRef(ref, output, _, _)) and
21682188
n = 0 and
21692189
(
21702190
if output = ""
@@ -2280,6 +2300,17 @@ module Make<
22802300
)
22812301
}
22822302

2303+
/**
2304+
* Holds if `node` is specified as a barrier with the given kind in a MaD flow
2305+
* model.
2306+
*/
2307+
predicate isBarrierNode(InterpretNode node, string kind, string model) {
2308+
exists(InterpretNode ref, SourceSinkAccessPath output |
2309+
barrierElementRef(ref, output, kind, model) and
2310+
interpretOutput(output, output.getNumToken(), ref, node)
2311+
)
2312+
}
2313+
22832314
final private class SourceOrSinkElementFinal = SourceOrSinkElement;
22842315

22852316
signature predicate sourceOrSinkElementSig(

shared/mad/codeql/mad/ModelValidation.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ module KindValidation<KindValidationConfigSig Config> {
173173
or
174174
exists(string kind, string msg | Config::sinkKind(kind) |
175175
not kind instanceof ValidSinkKind and
176-
msg = "Invalid kind \"" + kind + "\" in sink model." and
176+
msg = "Invalid kind \"" + kind + "\" in sink or barrier model." and
177177
// The part of this message that refers to outdated sink kinds can be deleted after June 1st, 2024.
178178
if kind instanceof OutdatedSinkKind
179179
then result = msg + " " + kind.(OutdatedSinkKind).outdatedMessage()

0 commit comments

Comments
 (0)