Skip to content

Commit 157403e

Browse files
committed
Rust: Source/sink/barrier MaD trait models apply to implementations
1 parent c8783c1 commit 157403e

5 files changed

Lines changed: 216 additions & 170 deletions

File tree

rust/ql/lib/codeql/rust/dataflow/internal/ModelsAsData.qll

Lines changed: 52 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,24 @@ predicate interpretModelForTest(QlBuiltins::ExtensionId madId, string model) {
174174
)
175175
}
176176

177+
bindingset[path, orig]
178+
pragma[inline_late]
179+
private predicate interpretPath(
180+
string path, Function f, Provenance orig, Provenance p, boolean isExact
181+
) {
182+
exists(Function f0 | f0.getCanonicalPath() = path |
183+
f = f0 and
184+
isExact = true and
185+
p = orig
186+
or
187+
f.implements(f0) and
188+
isExact = false and
189+
// making inherited models generated means that source code definitions and
190+
// exact generated models take precedence
191+
p = "hq-generated"
192+
)
193+
}
194+
177195
private class SummarizedCallableFromModel extends SummarizedCallable::Range {
178196
string input_;
179197
string output_;
@@ -183,19 +201,9 @@ private class SummarizedCallableFromModel extends SummarizedCallable::Range {
183201
QlBuiltins::ExtensionId madId;
184202

185203
SummarizedCallableFromModel() {
186-
exists(string path, Function f, Provenance p |
204+
exists(string path, Provenance p |
187205
summaryModel(path, input_, output_, kind, p, madId) and
188-
f.getCanonicalPath() = path
189-
|
190-
this = f and
191-
isExact_ = true and
192-
p_ = p
193-
or
194-
this.implements(f) and
195-
isExact_ = false and
196-
// making inherited models generated means that source code definitions and
197-
// exact generated models take precedence
198-
p_ = "hq-generated"
206+
interpretPath(path, this, p, p_, isExact_)
199207
)
200208
}
201209

@@ -246,16 +254,20 @@ private class SummarizedCallableWithCallback extends SummarizedCallable::Range {
246254

247255
private class FlowSourceFromModel extends FlowSource::Range {
248256
private string path;
257+
private Provenance p_;
249258

250259
FlowSourceFromModel() {
251-
sourceModel(path, _, _, _, _) and
252-
this.getCanonicalPath() = path
260+
exists(Provenance p |
261+
sourceModel(path, _, _, p, _) and
262+
interpretPath(path, this, p, p_, _)
263+
)
253264
}
254265

255266
override predicate isSource(string output, string kind, Provenance provenance, string model) {
256267
exists(QlBuiltins::ExtensionId madId |
257-
sourceModel(path, output, kind, provenance, madId) and
258-
model = "MaD:" + madId.toString()
268+
sourceModel(path, output, kind, _, madId) and
269+
model = "MaD:" + madId.toString() and
270+
provenance = p_
259271
) and
260272
// Only apply generated models when no neutral model exists
261273
// (the shared code only applies neutral models to summaries at present)
@@ -268,16 +280,20 @@ private class FlowSourceFromModel extends FlowSource::Range {
268280

269281
private class FlowSinkFromModel extends FlowSink::Range {
270282
private string path;
283+
private Provenance p_;
271284

272285
FlowSinkFromModel() {
273-
sinkModel(path, _, _, _, _) and
274-
this.getCanonicalPath() = path
286+
exists(Provenance p |
287+
sinkModel(path, _, _, p, _) and
288+
interpretPath(path, this, p, p_, _)
289+
)
275290
}
276291

277292
override predicate isSink(string input, string kind, Provenance provenance, string model) {
278293
exists(QlBuiltins::ExtensionId madId |
279-
sinkModel(path, input, kind, provenance, madId) and
280-
model = "MaD:" + madId.toString()
294+
sinkModel(path, input, kind, _, madId) and
295+
model = "MaD:" + madId.toString() and
296+
provenance = p_
281297
) and
282298
// Only apply generated models when no neutral model exists
283299
// (the shared code only applies neutral models to summaries at present)
@@ -290,34 +306,42 @@ private class FlowSinkFromModel extends FlowSink::Range {
290306

291307
private class FlowBarrierFromModel extends FlowBarrier::Range {
292308
private string path;
309+
private Provenance p_;
293310

294311
FlowBarrierFromModel() {
295-
barrierModel(path, _, _, _, _) and
296-
this.getCanonicalPath() = path
312+
exists(Provenance p |
313+
barrierModel(path, _, _, p, _) and
314+
interpretPath(path, this, p, p_, _)
315+
)
297316
}
298317

299318
override predicate isBarrier(string output, string kind, Provenance provenance, string model) {
300319
exists(QlBuiltins::ExtensionId madId |
301-
barrierModel(path, output, kind, provenance, madId) and
302-
model = "MaD:" + madId.toString()
320+
barrierModel(path, output, kind, _, madId) and
321+
model = "MaD:" + madId.toString() and
322+
provenance = p_
303323
)
304324
}
305325
}
306326

307327
private class FlowBarrierGuardFromModel extends FlowBarrierGuard::Range {
308328
private string path;
329+
private Provenance p_;
309330

310331
FlowBarrierGuardFromModel() {
311-
barrierGuardModel(path, _, _, _, _, _) and
312-
this.getCanonicalPath() = path
332+
exists(Provenance p |
333+
barrierGuardModel(path, _, _, _, p, _) and
334+
interpretPath(path, this, p, p_, _)
335+
)
313336
}
314337

315338
override predicate isBarrierGuard(
316339
string input, string acceptingValue, string kind, Provenance provenance, string model
317340
) {
318341
exists(QlBuiltins::ExtensionId madId |
319-
barrierGuardModel(path, input, acceptingValue, kind, provenance, madId) and
320-
model = "MaD:" + madId.toString()
342+
barrierGuardModel(path, input, acceptingValue, kind, _, madId) and
343+
model = "MaD:" + madId.toString() and
344+
provenance = p_
321345
)
322346
}
323347
}

rust/ql/test/library-tests/dataflow/barrier/inline-flow.expected

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ edges
44
| main.rs:21:13:21:21 | source(...) | main.rs:21:9:21:9 | s | provenance | |
55
| main.rs:32:9:32:9 | s | main.rs:33:10:33:10 | s | provenance | |
66
| main.rs:32:13:32:21 | source(...) | main.rs:32:9:32:9 | s | provenance | |
7-
| main.rs:63:9:63:9 | s | main.rs:65:10:65:10 | s | provenance | |
8-
| main.rs:63:13:63:21 | source(...) | main.rs:63:9:63:9 | s | provenance | |
97
nodes
108
| main.rs:17:10:17:18 | source(...) | semmle.label | source(...) |
119
| main.rs:21:9:21:9 | s | semmle.label | s |
@@ -14,13 +12,9 @@ nodes
1412
| main.rs:32:9:32:9 | s | semmle.label | s |
1513
| main.rs:32:13:32:21 | source(...) | semmle.label | source(...) |
1614
| main.rs:33:10:33:10 | s | semmle.label | s |
17-
| main.rs:63:9:63:9 | s | semmle.label | s |
18-
| main.rs:63:13:63:21 | source(...) | semmle.label | source(...) |
19-
| main.rs:65:10:65:10 | s | semmle.label | s |
2015
subpaths
2116
testFailures
2217
#select
2318
| main.rs:17:10:17:18 | source(...) | main.rs:17:10:17:18 | source(...) | main.rs:17:10:17:18 | source(...) | $@ | main.rs:17:10:17:18 | source(...) | source(...) |
2419
| main.rs:22:10:22:10 | s | main.rs:21:13:21:21 | source(...) | main.rs:22:10:22:10 | s | $@ | main.rs:21:13:21:21 | source(...) | source(...) |
2520
| main.rs:33:10:33:10 | s | main.rs:32:13:32:21 | source(...) | main.rs:33:10:33:10 | s | $@ | main.rs:32:13:32:21 | source(...) | source(...) |
26-
| main.rs:65:10:65:10 | s | main.rs:63:13:63:21 | source(...) | main.rs:65:10:65:10 | s | $@ | main.rs:63:13:63:21 | source(...) | source(...) |

rust/ql/test/library-tests/dataflow/barrier/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ impl<T> MyBarrierTrait3 for T {
6262
fn with_trait_barriers() {
6363
let s = source(2);
6464
<()>::sanitize2(s);
65-
sink(s); // $ SPURIOUS: hasValueFlow=2
65+
sink(s);
6666
<()>::sanitize3(s);
6767
sink(s);
6868
}

rust/ql/test/library-tests/dataflow/models/main.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -527,12 +527,12 @@ fn test_trait_model<T: Ord>(x: T) {
527527
sink(x9); // $ hasValueFlow=30
528528

529529
let x10 = <()>::produce2(31);
530-
sink(x10); // $ MISSING: hasValueFlow=31
530+
sink(x10); // $ hasValueFlow=31
531531

532532
let x11 = <()>::produce3(32);
533533
sink(x11); // $ hasValueFlow=32
534534

535-
<()>::consume2(source(33)); // $ MISSING: hasValueFlow=33
535+
<()>::consume2(source(33)); // $ hasValueFlow=33
536536

537537
<()>::consume3(source(34)); // $ hasValueFlow=34
538538
}

0 commit comments

Comments
 (0)