Skip to content

Commit db0fc7b

Browse files
authored
Merge pull request #19881 from hvitved/rust/dataflow-traits
Rust: Data flow through trait methods
2 parents b446fe7 + 9a48459 commit db0fc7b

File tree

15 files changed

+942
-578
lines changed

15 files changed

+942
-578
lines changed

rust/ql/.generated.list

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rust/ql/.gitattributes

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* Implemented support for data flow through trait functions. For the purpose of data flow, calls to trait functions dispatch to all possible implementations.

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

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -404,10 +404,20 @@ module RustDataFlow implements InputSig<Location> {
404404

405405
/** Gets a viable implementation of the target of the given `Call`. */
406406
DataFlowCallable viableCallable(DataFlowCall call) {
407-
exists(Callable target | target = call.asCallCfgNode().getCall().getStaticTarget() |
408-
target = result.asCfgScope()
407+
exists(Call c | c = call.asCallCfgNode().getCall() |
408+
result.asCfgScope() = c.getARuntimeTarget()
409409
or
410-
target = result.asSummarizedCallable()
410+
exists(SummarizedCallable sc, Function staticTarget |
411+
staticTarget = c.getStaticTarget() and
412+
sc = result.asSummarizedCallable()
413+
|
414+
sc = staticTarget
415+
or
416+
// only apply trait models to concrete implementations when they are not
417+
// defined in source code
418+
staticTarget.implements(sc) and
419+
not staticTarget.fromSource()
420+
)
411421
)
412422
}
413423

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
* - `Field[t(i)]`: position `i` inside the variant/struct with canonical path `v`, for example
3333
* `Field[core::option::Option::Some(0)]`.
3434
* - `Field[i]`: the `i`th element of a tuple.
35+
* - `Reference`: the referenced value.
36+
* - `Future`: the value being computed asynchronously.
3537
* 3. The `kind` column is a tag that can be referenced from QL to determine to
3638
* which classes the interpreted elements should be added. For example, for
3739
* sources `"remote"` indicates a default remote flow source, and for summaries
@@ -211,6 +213,10 @@ private class SummarizedCallableFromModel extends SummarizedCallable::Range {
211213
this.getCanonicalPath() = path
212214
}
213215

216+
override predicate hasProvenance(Provenance provenance) {
217+
summaryModel(path, _, _, _, provenance, _)
218+
}
219+
214220
override predicate propagatesFlow(
215221
string input, string output, boolean preservesValue, string model
216222
) {

rust/ql/lib/codeql/rust/elements/internal/AssocItemImpl.qll

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
// generated by codegen, remove this comment if you wish to edit this file
21
/**
32
* This module provides a hand-modifiable wrapper around the generated class `AssocItem`.
43
*
@@ -12,6 +11,10 @@ private import codeql.rust.elements.internal.generated.AssocItem
1211
* be referenced directly.
1312
*/
1413
module Impl {
14+
private import rust
15+
private import codeql.rust.internal.PathResolution
16+
17+
// the following QLdoc is generated: if you need to edit it, do it in the schema file
1518
/**
1619
* An associated item in a `Trait` or `Impl`.
1720
*
@@ -21,5 +24,15 @@ module Impl {
2124
* // ^^^^^^^^^^^^^
2225
* ```
2326
*/
24-
class AssocItem extends Generated::AssocItem { }
27+
class AssocItem extends Generated::AssocItem {
28+
/** Holds if this item implements trait item `other`. */
29+
pragma[nomagic]
30+
predicate implements(AssocItem other) {
31+
exists(TraitItemNode t, ImplItemNode i, string name |
32+
other = t.getAssocItem(pragma[only_bind_into](name)) and
33+
t = i.resolveTraitTy() and
34+
this = i.getAssocItem(pragma[only_bind_into](name))
35+
)
36+
}
37+
}
2538
}

rust/ql/lib/codeql/rust/elements/internal/CallImpl.qll

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,17 @@ module Impl {
6565
not exists(TypeInference::resolveMethodCallTarget(this)) and
6666
result = this.(CallExpr).getStaticTarget()
6767
}
68+
69+
/** Gets a runtime target of this call, if any. */
70+
pragma[nomagic]
71+
Function getARuntimeTarget() {
72+
result.hasImplementation() and
73+
(
74+
result = this.getStaticTarget()
75+
or
76+
result.implements(this.getStaticTarget())
77+
)
78+
}
6879
}
6980

7081
/** Holds if the call expression dispatches to a trait method. */

rust/ql/lib/codeql/rust/internal/PathResolution.qll

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,13 @@ abstract class ImplOrTraitItemNode extends ItemNode {
540540
/** Gets an associated item belonging to this trait or `impl` block. */
541541
abstract AssocItemNode getAnAssocItem();
542542

543+
/** Gets the associated item named `name` belonging to this trait or `impl` block. */
544+
pragma[nomagic]
545+
AssocItemNode getAssocItem(string name) {
546+
result = this.getAnAssocItem() and
547+
result.getName() = name
548+
}
549+
543550
/** Holds if this trait or `impl` block declares an associated item named `name`. */
544551
pragma[nomagic]
545552
predicate hasAssocItem(string name) { name = this.getAnAssocItem().getName() }
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
multipleCallTargets
2-
| main.rs:225:14:225:29 | ...::deref(...) |
2+
| main.rs:272:14:272:29 | ...::deref(...) |

0 commit comments

Comments
 (0)