diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll index f0da3cd38f7..12fe49ac97b 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll @@ -306,7 +306,11 @@ predicate indexAssignment( not index.getResolvedTarget().fromSource() } -module RustDataFlow implements InputSig { +signature module RustDataFlowInputSig { + predicate includeDynamicTargets(); +} + +module RustDataFlowGen implements InputSig { private import Aliases private import codeql.rust.dataflow.DataFlow private import Node as Node @@ -462,7 +466,11 @@ module RustDataFlow implements InputSig { /** 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 { class DataFlowSecondLevelScope = Void; } +module RustDataFlowInput implements RustDataFlowInputSig { + predicate includeDynamicTargets() { any() } +} + +module RustDataFlow = RustDataFlowGen; + /** 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() diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/TaintTrackingImpl.qll b/rust/ql/lib/codeql/rust/dataflow/internal/TaintTrackingImpl.qll index a7c58c53dd1..f75c0166762 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/TaintTrackingImpl.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/TaintTrackingImpl.qll @@ -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 { +module RustTaintTrackingGen implements + InputSig> +{ + private module DataFlow = DataFlowImpl::RustDataFlowGen; + predicate defaultTaintSanitizer(DataFlow::Node node) { none() } /** @@ -53,7 +58,7 @@ module RustTaintTracking implements InputSig { // 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 { ) 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 { 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 { */ predicate speculativeTaintStep(DataFlow::Node src, DataFlow::Node sink) { none() } } + +module RustTaintTracking = RustTaintTrackingGen; diff --git a/rust/ql/src/utils/modelgenerator/internal/CaptureModels.qll b/rust/ql/src/utils/modelgenerator/internal/CaptureModels.qll index 95cde0a8637..fb71423503d 100644 --- a/rust/ql/src/utils/modelgenerator/internal/CaptureModels.qll +++ b/rust/ql/src/utils/modelgenerator/internal/CaptureModels.qll @@ -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 -{ +private module RustDataFlowInput implements DataFlowImpl::RustDataFlowInputSig { + predicate includeDynamicTargets() { none() } +} + +module RustDataFlow = DataFlowImpl::RustDataFlowGen; + +module RustTaintTracking = TaintTrackingImpl::RustTaintTrackingGen; + +module ModelGeneratorCommonInput implements ModelGeneratorCommonInputSig { // 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 +private import MakeModelGeneratorFactory private module SummaryModelGeneratorInput implements SummaryModelGeneratorInputSig { class SummaryTargetApi extends QualifiedCallable {