Skip to content

Commit d400713

Browse files
committed
Rust: Implement neutral models for Rust.
1 parent 97f7dcb commit d400713

File tree

3 files changed

+139
-130
lines changed

3 files changed

+139
-130
lines changed

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

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,15 @@ extensible predicate summaryModel(
8989
QlBuiltins::ExtensionId madId
9090
);
9191

92+
/**
93+
* Holds if a neutral model of kind `kind` exists for the function with canonical path `path`. The
94+
* only effect of a neutral model is to prevent generated and inherited models of the corresponding
95+
* `kind` (`source`, `sink` or `summary`) from being applied.
96+
*/
97+
extensible predicate neutralModel(
98+
string path, string kind, string provenance, QlBuiltins::ExtensionId madId
99+
);
100+
92101
/**
93102
* Holds if the given extension tuple `madId` should pretty-print as `model`.
94103
*
@@ -109,6 +118,11 @@ predicate interpretModelForTest(QlBuiltins::ExtensionId madId, string model) {
109118
summaryModel(path, input, output, kind, _, madId) and
110119
model = "Summary: " + path + "; " + input + "; " + output + "; " + kind
111120
)
121+
or
122+
exists(string path, string kind |
123+
neutralModel(path, kind, _, madId) and
124+
model = "Neutral: " + path + "; " + kind
125+
)
112126
}
113127

114128
private predicate summaryModel(
@@ -133,16 +147,19 @@ private predicate summaryModelRelevant(
133147
) {
134148
summaryModel(f, input, output, kind, provenance, isInherited, madId) and
135149
// Only apply generated or inherited models to functions in library code and
136-
// when no strictly better model exists
137-
if provenance.isGenerated() or isInherited = true
138-
then
139-
not f.fromSource() and
140-
not exists(Provenance other | summaryModel(f, _, _, _, other, false, _) |
141-
provenance.isGenerated() and other.isManual()
142-
or
143-
provenance = other and isInherited = true
144-
)
145-
else any()
150+
// when no strictly better model (or neutral model) exists
151+
(
152+
if provenance.isGenerated() or isInherited = true
153+
then
154+
not f.fromSource() and
155+
not exists(Provenance other | summaryModel(f, _, _, _, other, false, _) |
156+
provenance.isGenerated() and other.isManual()
157+
or
158+
provenance = other and isInherited = true
159+
) and
160+
not neutralModel(f.getCanonicalPath(), "summary", _, _)
161+
else any()
162+
)
146163
}
147164

148165
private class SummarizedCallableFromModel extends SummarizedCallable::Range {
@@ -180,6 +197,11 @@ private class FlowSourceFromModel extends FlowSource::Range {
180197
exists(QlBuiltins::ExtensionId madId |
181198
sourceModel(path, output, kind, provenance, madId) and
182199
model = "MaD:" + madId.toString()
200+
) and
201+
// Only apply generated models when no neutral model exists
202+
not (
203+
provenance.isGenerated() and
204+
neutralModel(path, "source", _, _)
183205
)
184206
}
185207
}
@@ -196,6 +218,11 @@ private class FlowSinkFromModel extends FlowSink::Range {
196218
exists(QlBuiltins::ExtensionId madId |
197219
sinkModel(path, input, kind, provenance, madId) and
198220
model = "MaD:" + madId.toString()
221+
) and
222+
// Only apply generated models when no neutral model exists
223+
not (
224+
provenance.isGenerated() and
225+
neutralModel(path, "sink", _, _)
199226
)
200227
}
201228
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -434,10 +434,10 @@ fn test_neutrals() {
434434
// generated and a neutral model, should not have flow.
435435

436436
sink(generated_source(1)); // $ hasValueFlow=1
437-
sink(neutral_generated_source(2)); // $ SPURIOUS: hasValueFlow=2
437+
sink(neutral_generated_source(2));
438438
sink(neutral_manual_source(3)); // $ hasValueFlow=3
439439
generated_sink(source(4)); // $ hasValueFlow=4
440-
neutral_generated_sink(source(5)); // $ SPURIOUS: hasValueFlow=5
440+
neutral_generated_sink(source(5));
441441
neutral_manual_sink(source(6)); // $ hasValueFlow=6
442442
}
443443

0 commit comments

Comments
 (0)