Skip to content

Commit 8ffed9d

Browse files
committed
Rust: Refactor MaD provanance-based filtering
1 parent 27874ca commit 8ffed9d

File tree

9 files changed

+150
-144
lines changed

9 files changed

+150
-144
lines changed

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

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ final class DataFlowCallable extends TDataFlowCallable {
4747

4848
/** Gets a textual representation of this callable. */
4949
string toString() {
50-
result = [this.asCfgScope().toString(), this.asSummarizedCallable().toString()]
50+
result = [this.asCfgScope().toString(), "[summarized] " + this.asSummarizedCallable()]
5151
}
5252

5353
/** Gets the location of this callable. */
@@ -443,25 +443,7 @@ module RustDataFlow implements InputSig<Location> {
443443
exists(Call c | c = call.asCall() |
444444
result.asCfgScope() = c.getARuntimeTarget()
445445
or
446-
exists(SummarizedCallable sc, Function staticTarget |
447-
staticTarget = getStaticTargetExt(c) and
448-
sc = result.asSummarizedCallable() and
449-
// Only use summarized callables with generated summaries in case
450-
// the static call target is not in the source code.
451-
// Note that if `applyGeneratedModel` holds it implies that there doesn't
452-
// exist a manual model.
453-
not (
454-
staticTarget.fromSource() and
455-
sc.applyGeneratedModel()
456-
)
457-
|
458-
sc = staticTarget
459-
or
460-
// only apply trait models to concrete implementations when they are not
461-
// defined in source code
462-
staticTarget.implements(sc) and
463-
not staticTarget.fromSource()
464-
)
446+
result.asSummarizedCallable() = getStaticTargetExt(c)
465447
)
466448
}
467449

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

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -111,27 +111,61 @@ predicate interpretModelForTest(QlBuiltins::ExtensionId madId, string model) {
111111
)
112112
}
113113

114-
private class SummarizedCallableFromModel extends SummarizedCallable::Range {
115-
private string path;
114+
private predicate summaryModel(
115+
Function f, string input, string output, string kind, Provenance provenance, boolean isExact,
116+
QlBuiltins::ExtensionId madId
117+
) {
118+
exists(string path, Function f0 |
119+
summaryModel(path, input, output, kind, provenance, madId) and
120+
f0.getCanonicalPath() = path
121+
|
122+
f = f0 and
123+
isExact = true
124+
or
125+
f.implements(f0) and
126+
isExact = false
127+
)
128+
}
116129

117-
SummarizedCallableFromModel() {
118-
summaryModel(path, _, _, _, _, _) and
119-
this.getCanonicalPath() = path
120-
}
130+
private predicate summaryModelRelevant(
131+
Function f, string input, string output, string kind, Provenance provenance,
132+
QlBuiltins::ExtensionId madId
133+
) {
134+
exists(boolean isExact | summaryModel(f, input, output, kind, provenance, isExact, madId) |
135+
(
136+
provenance.isManual()
137+
or
138+
// only apply generated models to functions not defined in source code, and
139+
// when there are no exact manual models for the functions
140+
provenance.isGenerated() and
141+
not any(Provenance manual | summaryModel(f, _, _, _, manual, true, _)).isManual() and
142+
not f.fromSource()
143+
) and
144+
(
145+
isExact = true
146+
or
147+
// only apply trait models to concrete implementations when they are not
148+
// defined in source code, and when there are no exact model for the functions
149+
isExact = false and
150+
not summaryModel(f, _, _, _, provenance, true, _) and
151+
not f.fromSource()
152+
)
153+
)
154+
}
155+
156+
private class SummarizedCallableFromModel extends SummarizedCallable::Range {
157+
SummarizedCallableFromModel() { summaryModelRelevant(this, _, _, _, _, _) }
121158

122159
override predicate hasProvenance(Provenance provenance) {
123-
summaryModel(path, _, _, _, provenance, _)
160+
summaryModelRelevant(this, _, _, _, provenance, _)
124161
}
125162

126-
private predicate hasManualModel() { summaryModel(path, _, _, _, "manual", _) }
127-
128163
override predicate propagatesFlow(
129164
string input, string output, boolean preservesValue, string model
130165
) {
131166
exists(string kind, string provenance, QlBuiltins::ExtensionId madId |
132-
summaryModel(path, input, output, kind, provenance, madId) and
133-
model = "MaD:" + madId.toString() and
134-
(provenance = "manual" or not this.hasManualModel())
167+
summaryModelRelevant(this, input, output, kind, provenance, madId) and
168+
model = "MaD:" + madId.toString()
135169
|
136170
kind = "value" and
137171
preservesValue = true

rust/ql/lib/codeql/rust/frameworks/stdlib/alloc.model.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,5 +50,8 @@ extensions:
5050
- ["<alloc::string::String>::as_str", "Argument[self]", "ReturnValue", "value", "manual"]
5151
- ["<alloc::string::String>::as_bytes", "Argument[self]", "ReturnValue", "value", "manual"]
5252
- ["<_ as alloc::string::ToString>::to_string", "Argument[self].Reference", "ReturnValue", "taint", "manual"]
53+
# Overwrite generated model
54+
- ["<alloc::string::String as core::ops::arith::Add>::add", "Argument[self,0]", "ReturnValue", "taint", "manual"]
55+
- ["<alloc::string::String as core::ops::arith::Add>::add", "Argument[0].Reference", "ReturnValue", "taint", "manual"]
5356
# Vec
5457
- ["alloc::vec::from_elem", "Argument[0]", "ReturnValue.Element", "value", "manual"]

rust/ql/test/library-tests/dataflow/global/viableCallable.expected

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
| main.rs:2:5:2:12 | ... + ... | {EXTERNAL LOCATION} | fn add |
1+
| main.rs:2:5:2:12 | ... + ... | {EXTERNAL LOCATION} | [summarized] fn add |
22
| main.rs:13:5:13:13 | source(...) | main.rs:1:1:3:1 | fn source |
33
| main.rs:17:13:17:23 | get_data(...) | main.rs:12:1:14:1 | fn get_data |
44
| main.rs:18:5:18:11 | sink(...) | main.rs:5:1:7:1 | fn sink |
@@ -60,7 +60,7 @@
6060
| main.rs:228:13:228:34 | ...::new(...) | main.rs:221:5:224:5 | fn new |
6161
| main.rs:228:24:228:33 | source(...) | main.rs:1:1:3:1 | fn source |
6262
| main.rs:230:5:230:11 | sink(...) | main.rs:5:1:7:1 | fn sink |
63-
| main.rs:252:11:252:15 | * ... | {EXTERNAL LOCATION} | fn deref |
63+
| main.rs:252:11:252:15 | * ... | {EXTERNAL LOCATION} | [summarized] fn deref |
6464
| main.rs:258:28:258:36 | source(...) | main.rs:1:1:3:1 | fn source |
6565
| main.rs:260:13:260:17 | ... + ... | main.rs:236:5:239:5 | fn add |
6666
| main.rs:261:5:261:17 | sink(...) | main.rs:5:1:7:1 | fn sink |
@@ -77,7 +77,7 @@
7777
| main.rs:282:5:282:10 | ... *= ... | main.rs:243:5:245:5 | fn mul_assign |
7878
| main.rs:283:5:283:17 | sink(...) | main.rs:5:1:7:1 | fn sink |
7979
| main.rs:286:28:286:37 | source(...) | main.rs:1:1:3:1 | fn source |
80-
| main.rs:288:13:288:29 | * ... | {EXTERNAL LOCATION} | fn deref |
80+
| main.rs:288:13:288:29 | * ... | {EXTERNAL LOCATION} | [summarized] fn deref |
8181
| main.rs:288:14:288:29 | ...::deref(...) | main.rs:251:5:253:5 | fn deref |
8282
| main.rs:289:5:289:11 | sink(...) | main.rs:5:1:7:1 | fn sink |
8383
| main.rs:291:28:291:37 | source(...) | main.rs:1:1:3:1 | fn source |
@@ -101,14 +101,14 @@
101101
| main.rs:346:17:346:25 | source(...) | main.rs:1:1:3:1 | fn source |
102102
| main.rs:347:9:347:15 | sink(...) | main.rs:5:1:7:1 | fn sink |
103103
| main.rs:350:5:350:17 | sink(...) | main.rs:5:1:7:1 | fn sink |
104-
| main.rs:354:13:354:55 | ...::block_on(...) | {EXTERNAL LOCATION} | fn block_on |
104+
| main.rs:354:13:354:55 | ...::block_on(...) | {EXTERNAL LOCATION} | [summarized] fn block_on |
105105
| main.rs:354:41:354:54 | async_source(...) | main.rs:335:1:339:1 | fn async_source |
106106
| main.rs:355:5:355:11 | sink(...) | main.rs:5:1:7:1 | fn sink |
107-
| main.rs:357:5:357:62 | ...::block_on(...) | {EXTERNAL LOCATION} | fn block_on |
107+
| main.rs:357:5:357:62 | ...::block_on(...) | {EXTERNAL LOCATION} | [summarized] fn block_on |
108108
| main.rs:357:33:357:61 | test_async_await_async_part(...) | main.rs:341:1:351:1 | fn test_async_await_async_part |
109109
| main.rs:367:13:367:29 | self.get_number() | main.rs:378:9:380:9 | fn get_number |
110110
| main.rs:367:13:367:29 | self.get_number() | main.rs:386:9:388:9 | fn get_number |
111-
| main.rs:367:13:367:33 | ... * ... | {EXTERNAL LOCATION} | fn mul |
111+
| main.rs:367:13:367:33 | ... * ... | {EXTERNAL LOCATION} | [summarized] fn mul |
112112
| main.rs:371:13:371:21 | source(...) | main.rs:1:1:3:1 | fn source |
113113
| main.rs:379:13:379:21 | source(...) | main.rs:1:1:3:1 | fn source |
114114
| main.rs:391:13:391:22 | source(...) | main.rs:1:1:3:1 | fn source |

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

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,71 +1,69 @@
11
models
22
| 1 | Summary: <_ as alloc::string::ToString>::to_string; Argument[self].Reference; ReturnValue; taint |
33
| 2 | Summary: <_ as core::convert::From>::from; Argument[0]; ReturnValue; taint |
4-
| 3 | Summary: <_ as core::ops::arith::Add>::add; Argument[0].Reference; ReturnValue; taint |
5-
| 4 | Summary: <_ as core::ops::arith::Add>::add; Argument[self]; ReturnValue; taint |
6-
| 5 | Summary: <_ as core::ops::index::Index>::index; Argument[self].Reference.Element; ReturnValue.Reference; value |
7-
| 6 | Summary: <alloc::string::String as core::convert::From>::from; Argument[0].Reference; ReturnValue; value |
8-
| 7 | Summary: <alloc::string::String as core::ops::arith::Add>::add; Argument[self]; ReturnValue; value |
9-
| 8 | Summary: <alloc::string::String>::as_str; Argument[self]; ReturnValue; value |
10-
| 9 | Summary: alloc::fmt::format; Argument[0]; ReturnValue; taint |
11-
| 10 | Summary: core::hint::must_use; Argument[0]; ReturnValue; value |
4+
| 3 | Summary: <_ as core::ops::index::Index>::index; Argument[self].Reference.Element; ReturnValue.Reference; value |
5+
| 4 | Summary: <alloc::string::String as core::convert::From>::from; Argument[0].Reference; ReturnValue; value |
6+
| 5 | Summary: <alloc::string::String as core::ops::arith::Add>::add; Argument[0].Reference; ReturnValue; taint |
7+
| 6 | Summary: <alloc::string::String as core::ops::arith::Add>::add; Argument[self,0]; ReturnValue; taint |
8+
| 7 | Summary: <alloc::string::String>::as_str; Argument[self]; ReturnValue; value |
9+
| 8 | Summary: alloc::fmt::format; Argument[0]; ReturnValue; taint |
10+
| 9 | Summary: core::hint::must_use; Argument[0]; ReturnValue; value |
1211
edges
1312
| main.rs:26:9:26:9 | s | main.rs:27:19:27:19 | s | provenance | |
1413
| main.rs:26:9:26:9 | s | main.rs:27:19:27:25 | s[...] | provenance | |
1514
| main.rs:26:13:26:22 | source(...) | main.rs:26:9:26:9 | s | provenance | |
1615
| main.rs:27:9:27:14 | sliced [&ref] | main.rs:28:16:28:21 | sliced | provenance | |
1716
| main.rs:27:18:27:25 | &... [&ref] | main.rs:27:9:27:14 | sliced [&ref] | provenance | |
18-
| main.rs:27:19:27:19 | s | main.rs:27:19:27:25 | s[...] | provenance | MaD:5 |
17+
| main.rs:27:19:27:19 | s | main.rs:27:19:27:25 | s[...] | provenance | MaD:3 |
1918
| main.rs:27:19:27:25 | s[...] | main.rs:27:18:27:25 | &... [&ref] | provenance | |
2019
| main.rs:32:9:32:10 | s1 | main.rs:35:14:35:15 | s1 | provenance | |
2120
| main.rs:32:14:32:23 | source(...) | main.rs:32:9:32:10 | s1 | provenance | |
2221
| main.rs:35:9:35:10 | s4 | main.rs:38:10:38:11 | s4 | provenance | |
23-
| main.rs:35:14:35:15 | s1 | main.rs:35:14:35:20 | ... + ... | provenance | MaD:4 |
24-
| main.rs:35:14:35:15 | s1 | main.rs:35:14:35:20 | ... + ... | provenance | MaD:7 |
22+
| main.rs:35:14:35:15 | s1 | main.rs:35:14:35:20 | ... + ... | provenance | MaD:6 |
2523
| main.rs:35:14:35:20 | ... + ... | main.rs:35:9:35:10 | s4 | provenance | |
2624
| main.rs:43:9:43:10 | s1 | main.rs:46:34:46:35 | s1 | provenance | |
2725
| main.rs:43:14:43:23 | source(...) | main.rs:43:9:43:10 | s1 | provenance | |
28-
| main.rs:46:33:46:35 | &s1 [&ref] | main.rs:46:10:46:35 | ... + ... | provenance | MaD:3 |
26+
| main.rs:46:33:46:35 | &s1 [&ref] | main.rs:46:10:46:35 | ... + ... | provenance | MaD:5 |
2927
| main.rs:46:34:46:35 | s1 | main.rs:46:33:46:35 | &s1 [&ref] | provenance | |
3028
| main.rs:51:9:51:10 | s1 | main.rs:52:27:52:28 | s1 | provenance | |
3129
| main.rs:51:14:51:29 | source_slice(...) | main.rs:51:9:51:10 | s1 | provenance | |
3230
| main.rs:52:9:52:10 | s2 | main.rs:53:10:53:11 | s2 | provenance | |
3331
| main.rs:52:14:52:29 | ...::from(...) | main.rs:52:9:52:10 | s2 | provenance | |
3432
| main.rs:52:27:52:28 | s1 | main.rs:52:14:52:29 | ...::from(...) | provenance | MaD:2 |
35-
| main.rs:52:27:52:28 | s1 | main.rs:52:14:52:29 | ...::from(...) | provenance | MaD:6 |
33+
| main.rs:52:27:52:28 | s1 | main.rs:52:14:52:29 | ...::from(...) | provenance | MaD:4 |
3634
| main.rs:57:9:57:10 | s1 | main.rs:58:14:58:15 | s1 | provenance | |
3735
| main.rs:57:14:57:29 | source_slice(...) | main.rs:57:9:57:10 | s1 | provenance | |
3836
| main.rs:58:9:58:10 | s2 | main.rs:59:10:59:11 | s2 | provenance | |
3937
| main.rs:58:14:58:15 | s1 | main.rs:58:14:58:27 | s1.to_string() | provenance | MaD:1 |
4038
| main.rs:58:14:58:27 | s1.to_string() | main.rs:58:9:58:10 | s2 | provenance | |
4139
| main.rs:63:9:63:9 | s | main.rs:64:16:64:16 | s | provenance | |
4240
| main.rs:63:13:63:22 | source(...) | main.rs:63:9:63:9 | s | provenance | |
43-
| main.rs:64:16:64:16 | s | main.rs:64:16:64:25 | s.as_str() | provenance | MaD:8 |
41+
| main.rs:64:16:64:16 | s | main.rs:64:16:64:25 | s.as_str() | provenance | MaD:7 |
4442
| main.rs:68:9:68:9 | s | main.rs:70:34:70:61 | MacroExpr | provenance | |
4543
| main.rs:68:9:68:9 | s | main.rs:73:34:73:59 | MacroExpr | provenance | |
4644
| main.rs:68:13:68:22 | source(...) | main.rs:68:9:68:9 | s | provenance | |
4745
| main.rs:70:9:70:18 | formatted1 | main.rs:71:10:71:19 | formatted1 | provenance | |
4846
| main.rs:70:22:70:62 | ...::format(...) | main.rs:70:9:70:18 | formatted1 | provenance | |
49-
| main.rs:70:34:70:61 | MacroExpr | main.rs:70:22:70:62 | ...::format(...) | provenance | MaD:9 |
47+
| main.rs:70:34:70:61 | MacroExpr | main.rs:70:22:70:62 | ...::format(...) | provenance | MaD:8 |
5048
| main.rs:73:9:73:18 | formatted2 | main.rs:74:10:74:19 | formatted2 | provenance | |
5149
| main.rs:73:22:73:60 | ...::format(...) | main.rs:73:9:73:18 | formatted2 | provenance | |
52-
| main.rs:73:34:73:59 | MacroExpr | main.rs:73:22:73:60 | ...::format(...) | provenance | MaD:9 |
50+
| main.rs:73:34:73:59 | MacroExpr | main.rs:73:22:73:60 | ...::format(...) | provenance | MaD:8 |
5351
| main.rs:76:9:76:13 | width | main.rs:77:34:77:74 | MacroExpr | provenance | |
5452
| main.rs:76:17:76:32 | source_usize(...) | main.rs:76:9:76:13 | width | provenance | |
5553
| main.rs:77:9:77:18 | formatted3 | main.rs:78:10:78:19 | formatted3 | provenance | |
5654
| main.rs:77:22:77:75 | ...::format(...) | main.rs:77:9:77:18 | formatted3 | provenance | |
57-
| main.rs:77:34:77:74 | MacroExpr | main.rs:77:22:77:75 | ...::format(...) | provenance | MaD:9 |
55+
| main.rs:77:34:77:74 | MacroExpr | main.rs:77:22:77:75 | ...::format(...) | provenance | MaD:8 |
5856
| main.rs:82:9:82:10 | s1 | main.rs:86:18:86:25 | MacroExpr | provenance | |
5957
| main.rs:82:9:82:10 | s1 | main.rs:87:18:87:32 | MacroExpr | provenance | |
6058
| main.rs:82:14:82:23 | source(...) | main.rs:82:9:82:10 | s1 | provenance | |
6159
| main.rs:86:18:86:25 | ...::format(...) | main.rs:86:18:86:25 | { ... } | provenance | |
6260
| main.rs:86:18:86:25 | ...::must_use(...) | main.rs:86:10:86:26 | MacroExpr | provenance | |
63-
| main.rs:86:18:86:25 | MacroExpr | main.rs:86:18:86:25 | ...::format(...) | provenance | MaD:9 |
64-
| main.rs:86:18:86:25 | { ... } | main.rs:86:18:86:25 | ...::must_use(...) | provenance | MaD:10 |
61+
| main.rs:86:18:86:25 | MacroExpr | main.rs:86:18:86:25 | ...::format(...) | provenance | MaD:8 |
62+
| main.rs:86:18:86:25 | { ... } | main.rs:86:18:86:25 | ...::must_use(...) | provenance | MaD:9 |
6563
| main.rs:87:18:87:32 | ...::format(...) | main.rs:87:18:87:32 | { ... } | provenance | |
6664
| main.rs:87:18:87:32 | ...::must_use(...) | main.rs:87:10:87:33 | MacroExpr | provenance | |
67-
| main.rs:87:18:87:32 | MacroExpr | main.rs:87:18:87:32 | ...::format(...) | provenance | MaD:9 |
68-
| main.rs:87:18:87:32 | { ... } | main.rs:87:18:87:32 | ...::must_use(...) | provenance | MaD:10 |
65+
| main.rs:87:18:87:32 | MacroExpr | main.rs:87:18:87:32 | ...::format(...) | provenance | MaD:8 |
66+
| main.rs:87:18:87:32 | { ... } | main.rs:87:18:87:32 | ...::must_use(...) | provenance | MaD:9 |
6967
nodes
7068
| main.rs:26:9:26:9 | s | semmle.label | s |
7169
| main.rs:26:13:26:22 | source(...) | semmle.label | source(...) |

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ fn string_add() {
3535
let s4 = s1 + s3;
3636
let s5 = s2 + s3;
3737

38-
sink(s4); // $ SPURIOUS: hasValueFlow=83 MISSING: hasTaintFlow=83
38+
sink(s4); // $ hasTaintFlow=83
3939
sink(s5);
4040
}
4141

0 commit comments

Comments
 (0)