Skip to content

Commit 862adec

Browse files
committed
Rust: Disable dynamic dispatch when generating models
1 parent 1fbf038 commit 862adec

File tree

3 files changed

+51
-24
lines changed

3 files changed

+51
-24
lines changed

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

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,11 @@ predicate indexAssignment(
306306
not index.getResolvedTarget().fromSource()
307307
}
308308

309-
module RustDataFlow implements InputSig<Location> {
309+
signature module RustDataFlowInputSig {
310+
predicate includeDynamicTargets();
311+
}
312+
313+
module RustDataFlowGen<RustDataFlowInputSig Input> implements InputSig<Location> {
310314
private import Aliases
311315
private import codeql.rust.dataflow.DataFlow
312316
private import Node as Node
@@ -462,7 +466,11 @@ module RustDataFlow implements InputSig<Location> {
462466
/** Gets a viable implementation of the target of the given `Call`. */
463467
DataFlowCallable viableCallable(DataFlowCall call) {
464468
exists(Call c | c = call.asCall() |
465-
result.asCfgScope() = c.getARuntimeTarget()
469+
(
470+
if Input::includeDynamicTargets()
471+
then result.asCfgScope() = c.getARuntimeTarget()
472+
else result.asCfgScope() = c.getStaticTarget()
473+
)
466474
or
467475
result.asSummarizedCallable() = getStaticTargetExt(c)
468476
)
@@ -935,6 +943,12 @@ module RustDataFlow implements InputSig<Location> {
935943
class DataFlowSecondLevelScope = Void;
936944
}
937945

946+
module RustDataFlowInput implements RustDataFlowInputSig {
947+
predicate includeDynamicTargets() { any() }
948+
}
949+
950+
module RustDataFlow = RustDataFlowGen<RustDataFlowInput>;
951+
938952
/** Provides logic related to captured variables. */
939953
module VariableCapture {
940954
private import codeql.rust.internal.CachedStages
@@ -1110,7 +1124,7 @@ private module Cached {
11101124
}
11111125

11121126
cached
1113-
newtype TParameterPosition =
1127+
newtype TParameterPositionImpl =
11141128
TPositionalParameterPosition(int i) {
11151129
i in [0 .. max([any(ParamList l).getNumberOfParams(), any(ArgList l).getNumberOfArgs()]) - 1]
11161130
or
@@ -1121,6 +1135,8 @@ private module Cached {
11211135
TClosureSelfParameterPosition() or
11221136
TSelfParameterPosition()
11231137

1138+
final class TParameterPosition = TParameterPositionImpl;
1139+
11241140
cached
11251141
newtype TReturnKind = TNormalReturnKind()
11261142

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

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
private import rust
2+
private import codeql.dataflow.DataFlow as DF
23
private import codeql.dataflow.TaintTracking
3-
private import codeql.rust.dataflow.DataFlow
4+
private import codeql.rust.dataflow.DataFlow as RustDataFlow
45
private import codeql.rust.dataflow.FlowSummary
5-
private import DataFlowImpl
6+
private import DataFlowImpl as DataFlowImpl
67
private import Node as Node
78
private import Content
89
private import FlowSummaryImpl as FlowSummaryImpl
@@ -29,7 +30,11 @@ private predicate excludedTaintStepContent(Content c) {
2930
)
3031
}
3132

32-
module RustTaintTracking implements InputSig<Location, RustDataFlow> {
33+
module RustTaintTrackingGen<DataFlowImpl::RustDataFlowInputSig I> implements
34+
InputSig<Location, DataFlowImpl::RustDataFlowGen<I>>
35+
{
36+
private module DataFlow = DataFlowImpl::RustDataFlowGen<I>;
37+
3338
predicate defaultTaintSanitizer(DataFlow::Node node) { none() }
3439

3540
/**
@@ -53,7 +58,7 @@ module RustTaintTracking implements InputSig<Location, RustDataFlow> {
5358
// is tainted and an operation reads from `foo` (e.g., `foo.bar`) then
5459
// taint is propagated.
5560
exists(ContentSet cs |
56-
RustDataFlow::readStep(pred, cs, succ) and
61+
DataFlow::readStep(pred, cs, succ) and
5762
not excludedTaintStepContent(cs.getAReadContent())
5863
)
5964
or
@@ -70,9 +75,11 @@ module RustTaintTracking implements InputSig<Location, RustDataFlow> {
7075
)
7176
or
7277
succ.(Node::PostUpdateNode).getPreUpdateNode().asExpr() =
73-
getPostUpdateReverseStep(pred.(Node::PostUpdateNode).getPreUpdateNode().asExpr(), false)
78+
DataFlowImpl::getPostUpdateReverseStep(pred.(Node::PostUpdateNode)
79+
.getPreUpdateNode()
80+
.asExpr(), false)
7481
or
75-
indexAssignment(any(CompoundAssignmentExpr cae),
82+
DataFlowImpl::indexAssignment(any(CompoundAssignmentExpr cae),
7683
pred.(Node::PostUpdateNode).getPreUpdateNode().asExpr(), _, succ, _)
7784
)
7885
or
@@ -92,7 +99,7 @@ module RustTaintTracking implements InputSig<Location, RustDataFlow> {
9299
c instanceof ReferenceContent
93100
) and
94101
// Optional steps are added through isAdditionalFlowStep but we don't want the implicit reads
95-
not optionalStep(node, _, _)
102+
not DataFlowImpl::optionalStep(node, _, _)
96103
}
97104

98105
/**
@@ -101,3 +108,5 @@ module RustTaintTracking implements InputSig<Location, RustDataFlow> {
101108
*/
102109
predicate speculativeTaintStep(DataFlow::Node src, DataFlow::Node sink) { none() }
103110
}
111+
112+
module RustTaintTracking = RustTaintTrackingGen<DataFlowImpl::RustDataFlowInput>;

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

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ private import codeql.rust.dataflow.internal.Content
77
private import codeql.rust.dataflow.FlowSource as FlowSource
88
private import codeql.rust.dataflow.FlowSink as FlowSink
99
private import codeql.rust.dataflow.internal.TaintTrackingImpl
10+
private import codeql.rust.dataflow.internal.TaintTrackingImpl as TaintTrackingImpl
1011
private import codeql.mad.modelgenerator.internal.ModelGeneratorImpl
1112
private import codeql.rust.dataflow.internal.FlowSummaryImpl as FlowSummary
1213

@@ -42,9 +43,15 @@ class QualifiedCallable extends TCallable {
4243
string getCanonicalPath() { result = path }
4344
}
4445

45-
module ModelGeneratorCommonInput implements
46-
ModelGeneratorCommonInputSig<R::Location, DataFlowImpl::RustDataFlow>
47-
{
46+
private module RustDataFlowInput implements DataFlowImpl::RustDataFlowInputSig {
47+
predicate includeDynamicTargets() { none() }
48+
}
49+
50+
module RustDataFlow = DataFlowImpl::RustDataFlowGen<RustDataFlowInput>;
51+
52+
module RustTaintTracking = TaintTrackingImpl::RustTaintTrackingGen<RustDataFlowInput>;
53+
54+
module ModelGeneratorCommonInput implements ModelGeneratorCommonInputSig<R::Location, RustDataFlow> {
4855
// NOTE: We are not using type information for now.
4956
class Type = Unit;
5057

@@ -71,9 +78,8 @@ module ModelGeneratorCommonInput implements
7178

7279
string parameterExactAccess(R::ParamBase p) {
7380
result =
74-
"Argument[" +
75-
any(DataFlowImpl::RustDataFlow::ParameterPosition pos | p = pos.getParameterIn(_))
76-
.toString() + "]"
81+
"Argument[" + any(RustDataFlow::ParameterPosition pos | p = pos.getParameterIn(_)).toString() +
82+
"]"
7783
}
7884

7985
string parameterApproximateAccess(R::ParamBase p) { result = parameterExactAccess(p) }
@@ -83,16 +89,12 @@ module ModelGeneratorCommonInput implements
8389
}
8490

8591
bindingset[c]
86-
string paramReturnNodeAsApproximateOutput(
87-
QualifiedCallable c, DataFlowImpl::RustDataFlow::ParameterPosition pos
88-
) {
92+
string paramReturnNodeAsApproximateOutput(QualifiedCallable c, RustDataFlow::ParameterPosition pos) {
8993
result = paramReturnNodeAsExactOutput(c, pos)
9094
}
9195

9296
bindingset[c]
93-
string paramReturnNodeAsExactOutput(
94-
QualifiedCallable c, DataFlowImpl::RustDataFlow::ParameterPosition pos
95-
) {
97+
string paramReturnNodeAsExactOutput(QualifiedCallable c, RustDataFlow::ParameterPosition pos) {
9698
result = parameterExactAccess(c.getFunction().getParam(pos.getPosition()))
9799
or
98100
pos.isSelf() and result = qualifierString()
@@ -102,7 +104,7 @@ module ModelGeneratorCommonInput implements
102104
result.getFunction() = ret.(Node::Node).getEnclosingCallable().asCfgScope()
103105
}
104106

105-
predicate isOwnInstanceAccessNode(DataFlowImpl::RustDataFlow::ReturnNode node) {
107+
predicate isOwnInstanceAccessNode(RustDataFlow::ReturnNode node) {
106108
// This is probably not relevant to implement for Rust, as we only use
107109
// `captureMixedFlow` which doesn't explicitly distinguish between
108110
// functions that return `self` and those that don't.
@@ -121,7 +123,7 @@ module ModelGeneratorCommonInput implements
121123
}
122124

123125
private import ModelGeneratorCommonInput
124-
private import MakeModelGeneratorFactory<R::Location, DataFlowImpl::RustDataFlow, RustTaintTracking, ModelGeneratorCommonInput>
126+
private import MakeModelGeneratorFactory<R::Location, RustDataFlow, RustTaintTracking, ModelGeneratorCommonInput>
125127

126128
private module SummaryModelGeneratorInput implements SummaryModelGeneratorInputSig {
127129
class SummaryTargetApi extends QualifiedCallable {

0 commit comments

Comments
 (0)