mirror of
https://github.com/github/codeql.git
synced 2026-02-12 05:01:06 +01:00
Rust: Disable dynamic dispatch when generating models
This commit is contained in:
@@ -306,7 +306,11 @@ predicate indexAssignment(
|
||||
not index.getResolvedTarget().fromSource()
|
||||
}
|
||||
|
||||
module RustDataFlow implements InputSig<Location> {
|
||||
signature module RustDataFlowInputSig {
|
||||
predicate includeDynamicTargets();
|
||||
}
|
||||
|
||||
module RustDataFlowGen<RustDataFlowInputSig Input> implements InputSig<Location> {
|
||||
private import Aliases
|
||||
private import codeql.rust.dataflow.DataFlow
|
||||
private import Node as Node
|
||||
@@ -462,7 +466,11 @@ module RustDataFlow implements InputSig<Location> {
|
||||
/** Gets a viable implementation of the target of the given `Call`. */
|
||||
DataFlowCallable viableCallable(DataFlowCall call) {
|
||||
exists(Call c | c = call.asCall() |
|
||||
result.asCfgScope() = c.getARuntimeTarget()
|
||||
(
|
||||
if Input::includeDynamicTargets()
|
||||
then result.asCfgScope() = c.getARuntimeTarget()
|
||||
else result.asCfgScope() = c.getStaticTarget()
|
||||
)
|
||||
or
|
||||
result.asSummarizedCallable() = getStaticTargetExt(c)
|
||||
)
|
||||
@@ -935,6 +943,12 @@ module RustDataFlow implements InputSig<Location> {
|
||||
class DataFlowSecondLevelScope = Void;
|
||||
}
|
||||
|
||||
module RustDataFlowInput implements RustDataFlowInputSig {
|
||||
predicate includeDynamicTargets() { any() }
|
||||
}
|
||||
|
||||
module RustDataFlow = RustDataFlowGen<RustDataFlowInput>;
|
||||
|
||||
/** Provides logic related to captured variables. */
|
||||
module VariableCapture {
|
||||
private import codeql.rust.internal.CachedStages
|
||||
@@ -1110,7 +1124,7 @@ private module Cached {
|
||||
}
|
||||
|
||||
cached
|
||||
newtype TParameterPosition =
|
||||
newtype TParameterPositionImpl =
|
||||
TPositionalParameterPosition(int i) {
|
||||
i in [0 .. max([any(ParamList l).getNumberOfParams(), any(ArgList l).getNumberOfArgs()]) - 1]
|
||||
or
|
||||
@@ -1121,6 +1135,8 @@ private module Cached {
|
||||
TClosureSelfParameterPosition() or
|
||||
TSelfParameterPosition()
|
||||
|
||||
final class TParameterPosition = TParameterPositionImpl;
|
||||
|
||||
cached
|
||||
newtype TReturnKind = TNormalReturnKind()
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
private import rust
|
||||
private import codeql.dataflow.DataFlow as DF
|
||||
private import codeql.dataflow.TaintTracking
|
||||
private import codeql.rust.dataflow.DataFlow
|
||||
private import codeql.rust.dataflow.DataFlow as RustDataFlow
|
||||
private import codeql.rust.dataflow.FlowSummary
|
||||
private import DataFlowImpl
|
||||
private import DataFlowImpl as DataFlowImpl
|
||||
private import Node as Node
|
||||
private import Content
|
||||
private import FlowSummaryImpl as FlowSummaryImpl
|
||||
@@ -29,7 +30,11 @@ private predicate excludedTaintStepContent(Content c) {
|
||||
)
|
||||
}
|
||||
|
||||
module RustTaintTracking implements InputSig<Location, RustDataFlow> {
|
||||
module RustTaintTrackingGen<DataFlowImpl::RustDataFlowInputSig I> implements
|
||||
InputSig<Location, DataFlowImpl::RustDataFlowGen<I>>
|
||||
{
|
||||
private module DataFlow = DataFlowImpl::RustDataFlowGen<I>;
|
||||
|
||||
predicate defaultTaintSanitizer(DataFlow::Node node) { none() }
|
||||
|
||||
/**
|
||||
@@ -53,7 +58,7 @@ module RustTaintTracking implements InputSig<Location, RustDataFlow> {
|
||||
// is tainted and an operation reads from `foo` (e.g., `foo.bar`) then
|
||||
// taint is propagated.
|
||||
exists(ContentSet cs |
|
||||
RustDataFlow::readStep(pred, cs, succ) and
|
||||
DataFlow::readStep(pred, cs, succ) and
|
||||
not excludedTaintStepContent(cs.getAReadContent())
|
||||
)
|
||||
or
|
||||
@@ -70,9 +75,11 @@ module RustTaintTracking implements InputSig<Location, RustDataFlow> {
|
||||
)
|
||||
or
|
||||
succ.(Node::PostUpdateNode).getPreUpdateNode().asExpr() =
|
||||
getPostUpdateReverseStep(pred.(Node::PostUpdateNode).getPreUpdateNode().asExpr(), false)
|
||||
DataFlowImpl::getPostUpdateReverseStep(pred.(Node::PostUpdateNode)
|
||||
.getPreUpdateNode()
|
||||
.asExpr(), false)
|
||||
or
|
||||
indexAssignment(any(CompoundAssignmentExpr cae),
|
||||
DataFlowImpl::indexAssignment(any(CompoundAssignmentExpr cae),
|
||||
pred.(Node::PostUpdateNode).getPreUpdateNode().asExpr(), _, succ, _)
|
||||
)
|
||||
or
|
||||
@@ -92,7 +99,7 @@ module RustTaintTracking implements InputSig<Location, RustDataFlow> {
|
||||
c instanceof ReferenceContent
|
||||
) and
|
||||
// Optional steps are added through isAdditionalFlowStep but we don't want the implicit reads
|
||||
not optionalStep(node, _, _)
|
||||
not DataFlowImpl::optionalStep(node, _, _)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -101,3 +108,5 @@ module RustTaintTracking implements InputSig<Location, RustDataFlow> {
|
||||
*/
|
||||
predicate speculativeTaintStep(DataFlow::Node src, DataFlow::Node sink) { none() }
|
||||
}
|
||||
|
||||
module RustTaintTracking = RustTaintTrackingGen<DataFlowImpl::RustDataFlowInput>;
|
||||
|
||||
@@ -7,6 +7,7 @@ private import codeql.rust.dataflow.internal.Content
|
||||
private import codeql.rust.dataflow.FlowSource as FlowSource
|
||||
private import codeql.rust.dataflow.FlowSink as FlowSink
|
||||
private import codeql.rust.dataflow.internal.TaintTrackingImpl
|
||||
private import codeql.rust.dataflow.internal.TaintTrackingImpl as TaintTrackingImpl
|
||||
private import codeql.mad.modelgenerator.internal.ModelGeneratorImpl
|
||||
private import codeql.rust.dataflow.internal.FlowSummaryImpl as FlowSummary
|
||||
|
||||
@@ -42,9 +43,15 @@ class QualifiedCallable extends TCallable {
|
||||
string getCanonicalPath() { result = path }
|
||||
}
|
||||
|
||||
module ModelGeneratorCommonInput implements
|
||||
ModelGeneratorCommonInputSig<R::Location, DataFlowImpl::RustDataFlow>
|
||||
{
|
||||
private module RustDataFlowInput implements DataFlowImpl::RustDataFlowInputSig {
|
||||
predicate includeDynamicTargets() { none() }
|
||||
}
|
||||
|
||||
module RustDataFlow = DataFlowImpl::RustDataFlowGen<RustDataFlowInput>;
|
||||
|
||||
module RustTaintTracking = TaintTrackingImpl::RustTaintTrackingGen<RustDataFlowInput>;
|
||||
|
||||
module ModelGeneratorCommonInput implements ModelGeneratorCommonInputSig<R::Location, RustDataFlow> {
|
||||
// NOTE: We are not using type information for now.
|
||||
class Type = Unit;
|
||||
|
||||
@@ -71,9 +78,8 @@ module ModelGeneratorCommonInput implements
|
||||
|
||||
string parameterExactAccess(R::ParamBase p) {
|
||||
result =
|
||||
"Argument[" +
|
||||
any(DataFlowImpl::RustDataFlow::ParameterPosition pos | p = pos.getParameterIn(_))
|
||||
.toString() + "]"
|
||||
"Argument[" + any(RustDataFlow::ParameterPosition pos | p = pos.getParameterIn(_)).toString() +
|
||||
"]"
|
||||
}
|
||||
|
||||
string parameterApproximateAccess(R::ParamBase p) { result = parameterExactAccess(p) }
|
||||
@@ -83,16 +89,12 @@ module ModelGeneratorCommonInput implements
|
||||
}
|
||||
|
||||
bindingset[c]
|
||||
string paramReturnNodeAsApproximateOutput(
|
||||
QualifiedCallable c, DataFlowImpl::RustDataFlow::ParameterPosition pos
|
||||
) {
|
||||
string paramReturnNodeAsApproximateOutput(QualifiedCallable c, RustDataFlow::ParameterPosition pos) {
|
||||
result = paramReturnNodeAsExactOutput(c, pos)
|
||||
}
|
||||
|
||||
bindingset[c]
|
||||
string paramReturnNodeAsExactOutput(
|
||||
QualifiedCallable c, DataFlowImpl::RustDataFlow::ParameterPosition pos
|
||||
) {
|
||||
string paramReturnNodeAsExactOutput(QualifiedCallable c, RustDataFlow::ParameterPosition pos) {
|
||||
result = parameterExactAccess(c.getFunction().getParam(pos.getPosition()))
|
||||
or
|
||||
pos.isSelf() and result = qualifierString()
|
||||
@@ -102,7 +104,7 @@ module ModelGeneratorCommonInput implements
|
||||
result.getFunction() = ret.(Node::Node).getEnclosingCallable().asCfgScope()
|
||||
}
|
||||
|
||||
predicate isOwnInstanceAccessNode(DataFlowImpl::RustDataFlow::ReturnNode node) {
|
||||
predicate isOwnInstanceAccessNode(RustDataFlow::ReturnNode node) {
|
||||
// This is probably not relevant to implement for Rust, as we only use
|
||||
// `captureMixedFlow` which doesn't explicitly distinguish between
|
||||
// functions that return `self` and those that don't.
|
||||
@@ -121,7 +123,7 @@ module ModelGeneratorCommonInput implements
|
||||
}
|
||||
|
||||
private import ModelGeneratorCommonInput
|
||||
private import MakeModelGeneratorFactory<R::Location, DataFlowImpl::RustDataFlow, RustTaintTracking, ModelGeneratorCommonInput>
|
||||
private import MakeModelGeneratorFactory<R::Location, RustDataFlow, RustTaintTracking, ModelGeneratorCommonInput>
|
||||
|
||||
private module SummaryModelGeneratorInput implements SummaryModelGeneratorInputSig {
|
||||
class SummaryTargetApi extends QualifiedCallable {
|
||||
|
||||
Reference in New Issue
Block a user