Skip to content

Commit 79fd10d

Browse files
committed
Rust: move model generator to new format
1 parent 261c129 commit 79fd10d

File tree

2 files changed

+37
-32
lines changed

2 files changed

+37
-32
lines changed

rust/bulk_generation_targets.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
strategy: dca
22
language: rust
33
destination: rust/ql/lib/ext/generated
4+
single-file: true # dump models into a single file per crate (we do not have proper namespaces)
45
# targets must have name specified and corresponding to the name in the DCA suite
56
# they can optionally specify any of
67
# with-sinks: false

rust/ql/src/utils/modelgenerator/internal/CaptureModels.qll

Lines changed: 36 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -11,26 +11,32 @@ private import codeql.rust.dataflow.internal.TaintTrackingImpl
1111
private import codeql.mad.modelgenerator.internal.ModelGeneratorImpl
1212
private import codeql.rust.dataflow.internal.FlowSummaryImpl as FlowSummary
1313

14-
private predicate relevant(Function api) {
15-
// Only include functions that have a resolved path.
16-
api.hasCrateOrigin() and
17-
api.hasExtendedCanonicalPath() and
18-
// A canonical path can contain `;` as the syntax for array types use `;`. For
19-
// instance `<[Foo; 1] as Bar>::baz`. This does not work with the shared model
20-
// generator and it is not clear if this will also be the case when we move to
21-
// QL created canoonical paths, so for now we just exclude functions with
22-
// `;`s.
23-
not exists(api.getExtendedCanonicalPath().indexOf(";")) and
24-
(
25-
// This excludes closures (these are not exported API endpoints) and
26-
// functions without a `pub` visibility. A function can be `pub` without
27-
// ultimately being exported by a crate, so this is an overapproximation.
28-
api.hasVisibility()
29-
or
30-
// If a method implements a public trait it is exposed through the trait.
31-
// We overapproximate this by including all trait method implementations.
32-
exists(Impl impl | impl.hasTrait() and impl.getAssocItemList().getAssocItem(_) = api)
33-
)
14+
private newtype TCallable =
15+
TFunction(Function api, string path) {
16+
path = api.getCanonicalPath() and
17+
(
18+
// This excludes closures (these are not exported API endpoints) and
19+
// functions without a `pub` visibility. A function can be `pub` without
20+
// ultimately being exported by a crate, so this is an overapproximation.
21+
api.hasVisibility()
22+
or
23+
// If a method implements a public trait it is exposed through the trait.
24+
// We overapproximate this by including all trait method implementations.
25+
exists(Impl impl | impl.hasTrait() and impl.getAssocItemList().getAssocItem(_) = api)
26+
)
27+
}
28+
29+
private class QualifiedCallable extends TCallable {
30+
Function api;
31+
string path;
32+
33+
QualifiedCallable() { this = TFunction(api, path) }
34+
35+
string toString() { result = path }
36+
37+
Function asFunction() { result = api }
38+
39+
string getCanonicalPath() { result = path }
3440
}
3541

3642
module ModelGeneratorCommonInput implements
@@ -41,14 +47,14 @@ module ModelGeneratorCommonInput implements
4147

4248
class Parameter = R::ParamBase;
4349

44-
class Callable = R::Callable;
50+
class Callable = QualifiedCallable;
4551

4652
class NodeExtended extends DataFlow::Node {
4753
Type getType() { any() }
4854
}
4955

50-
Callable getEnclosingCallable(NodeExtended node) {
51-
result = node.(Node::Node).getEnclosingCallable().asCfgScope()
56+
QualifiedCallable getEnclosingCallable(NodeExtended node) {
57+
result.asFunction() = node.(Node::Node).getEnclosingCallable().asCfgScope()
5258
}
5359

5460
predicate isRelevantType(Type t) { any() }
@@ -73,19 +79,19 @@ module ModelGeneratorCommonInput implements
7379
}
7480

7581
bindingset[c]
76-
string paramReturnNodeAsApproximateOutput(Callable c, DataFlowImpl::ParameterPosition pos) {
82+
string paramReturnNodeAsApproximateOutput(QualifiedCallable c, DataFlowImpl::ParameterPosition pos) {
7783
result = paramReturnNodeAsExactOutput(c, pos)
7884
}
7985

8086
bindingset[c]
81-
string paramReturnNodeAsExactOutput(Callable c, DataFlowImpl::ParameterPosition pos) {
82-
result = parameterExactAccess(c.getParam(pos.getPosition()))
87+
string paramReturnNodeAsExactOutput(QualifiedCallable c, DataFlowImpl::ParameterPosition pos) {
88+
result = parameterExactAccess(c.asFunction().getParam(pos.getPosition()))
8389
or
8490
pos.isSelf() and result = qualifierString()
8591
}
8692

87-
Callable returnNodeEnclosingCallable(DataFlow::Node ret) {
88-
result = ret.(Node::Node).getEnclosingCallable().asCfgScope()
93+
QualifiedCallable returnNodeEnclosingCallable(DataFlow::Node ret) {
94+
result.asFunction() = ret.(Node::Node).getEnclosingCallable().asCfgScope()
8995
}
9096

9197
predicate isOwnInstanceAccessNode(DataFlowImpl::RustDataFlow::ReturnNode node) {
@@ -99,10 +105,8 @@ module ModelGeneratorCommonInput implements
99105
c.(SingletonContentSet).getContent() instanceof ElementContent
100106
}
101107

102-
string partialModelRow(Callable api, int i) {
103-
i = 0 and result = api.(Function).getCrateOrigin() // crate
104-
or
105-
i = 1 and result = api.(Function).getExtendedCanonicalPath() // name
108+
string partialModelRow(QualifiedCallable api, int i) {
109+
i = 0 and result = min(string path | path = api.(Function).getCanonicalPath() | path)
106110
}
107111

108112
string partialNeutralModelRow(Callable api, int i) { result = partialModelRow(api, i) }

0 commit comments

Comments
 (0)