Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rust: Add support for MaD sources and sinks with access paths #18298

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,14 @@ private import semmle.code.cpp.dataflow.ExternalFlow
private import semmle.code.cpp.ir.IR

module Input implements InputSig<Location, DataFlowImplSpecific::CppDataFlow> {
private import codeql.util.Void

class SummarizedCallableBase = Function;

class SourceBase = Void;

class SinkBase = Void;

ArgumentPosition callbackSelfParameterPosition() { result = TDirectPosition(-1) }

ReturnKind getStandardReturnValueKind() { result.(NormalReturnKind).getIndirectionIndex() = 0 }
Expand Down Expand Up @@ -93,6 +99,10 @@ private module StepsInput implements Impl::Private::StepsInputSig {
DataFlowCall getACall(Public::SummarizedCallable sc) {
result.getStaticCallTarget().getUnderlyingCallable() = sc
}

Node getSourceNode(Input::SourceBase source, Impl::Private::SummaryComponent sc) { none() }

Node getSinkNode(Input::SinkBase sink, Impl::Private::SummaryComponent sc) { none() }
}

module SourceSinkInterpretationInput implements
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,14 @@ private import semmle.code.csharp.Unification
private import semmle.code.csharp.dataflow.internal.ExternalFlow

module Input implements InputSig<Location, DataFlowImplSpecific::CsharpDataFlow> {
private import codeql.util.Void

class SummarizedCallableBase = UnboundCallable;

class SourceBase = Void;

class SinkBase = Void;

predicate neutralElement(SummarizedCallableBase c, string kind, string provenance, boolean isExact) {
interpretNeutral(c, kind, provenance) and
// isExact is not needed for C#.
Expand Down Expand Up @@ -176,12 +182,22 @@ private module TypesInput implements Impl::Private::TypesInputSig {
result.asGvnType() = Gvn::getGlobalValueNumber(dt.getDelegateType().getReturnType())
)
}

DataFlowType getSourceNodeType(Input::SourceBase source, Impl::Private::SummaryComponent sc) {
none()
}

DataFlowType getSinkNodeType(Input::SinkBase sink, Impl::Private::SummaryComponent sc) { none() }
}

private module StepsInput implements Impl::Private::StepsInputSig {
DataFlowCall getACall(Public::SummarizedCallable sc) {
sc = viableCallable(result).asSummarizedCallable()
}

Node getSourceNode(Input::SourceBase source, Impl::Private::SummaryComponent sc) { none() }

Node getSinkNode(Input::SinkBase sink, Impl::Private::SummaryComponent sc) { none() }
}

module SourceSinkInterpretationInput implements
Expand Down
12 changes: 6 additions & 6 deletions go/ql/lib/semmle/go/dataflow/ExternalFlow.qll
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ import internal.ExternalFlowExtensions as FlowExtensions
private import FlowSummary as FlowSummary
private import internal.DataFlowPrivate
private import internal.FlowSummaryImpl
private import internal.FlowSummaryImpl::Public
private import internal.FlowSummaryImpl::Public as Public
private import internal.FlowSummaryImpl::Private
private import internal.FlowSummaryImpl::Private::External
private import codeql.mad.ModelValidation as SharedModelVal
Expand Down Expand Up @@ -583,13 +583,13 @@ predicate sourceNode(DataFlow::Node node, string kind) { sourceNode(node, kind,
predicate sinkNode(DataFlow::Node node, string kind) { sinkNode(node, kind, _) }

// adapter class for converting Mad summaries to `SummarizedCallable`s
private class SummarizedCallableAdapter extends SummarizedCallable {
private class SummarizedCallableAdapter extends Public::SummarizedCallable {
SummarizedCallableAdapter() { summaryElement(this, _, _, _, _, _) }

private predicate relevantSummaryElementManual(
string input, string output, string kind, string model
) {
exists(Provenance provenance |
exists(Public::Provenance provenance |
summaryElement(this, input, output, kind, provenance, model) and
provenance.isManual()
)
Expand All @@ -598,11 +598,11 @@ private class SummarizedCallableAdapter extends SummarizedCallable {
private predicate relevantSummaryElementGenerated(
string input, string output, string kind, string model
) {
exists(Provenance provenance |
exists(Public::Provenance provenance |
summaryElement(this, input, output, kind, provenance, model) and
provenance.isGenerated()
) and
not exists(Provenance provenance |
not exists(Public::Provenance provenance |
neutralElement(this, "summary", provenance) and
provenance.isManual()
)
Expand All @@ -621,7 +621,7 @@ private class SummarizedCallableAdapter extends SummarizedCallable {
)
}

override predicate hasProvenance(Provenance provenance) {
override predicate hasProvenance(Public::Provenance provenance) {
summaryElement(this, _, _, _, provenance, _)
}
}
10 changes: 10 additions & 0 deletions go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,14 @@ private string positionToString(int pos) {
}

module Input implements InputSig<Location, DataFlowImplSpecific::GoDataFlow> {
private import codeql.util.Void

class SummarizedCallableBase = Callable;

class SourceBase = Void;

class SinkBase = Void;

predicate neutralElement(
Input::SummarizedCallableBase c, string kind, string provenance, boolean isExact
) {
Expand Down Expand Up @@ -108,6 +114,10 @@ private module StepsInput implements Impl::Private::StepsInputSig {
call.getACalleeIncludingExternals() = sc
)
}

Node getSourceNode(Input::SourceBase source, Impl::Private::SummaryComponent sc) { none() }

Node getSinkNode(Input::SinkBase sink, Impl::Private::SummaryComponent sc) { none() }
}

module SourceSinkInterpretationInput implements
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,14 @@ private string positionToString(int pos) {
}

module Input implements InputSig<Location, DataFlowImplSpecific::JavaDataFlow> {
private import codeql.util.Void

class SummarizedCallableBase = FlowSummary::SummarizedCallableBase;

class SourceBase = Void;

class SinkBase = Void;

predicate neutralElement(
Input::SummarizedCallableBase c, string kind, string provenance, boolean isExact
) {
Expand Down Expand Up @@ -123,12 +129,22 @@ private module TypesInput implements Impl::Private::TypesInputSig {
result = getErasedRepr(t.(FunctionalInterface).getRunMethod().getReturnType()) and
exists(rk)
}

DataFlowType getSourceNodeType(Input::SourceBase source, Impl::Private::SummaryComponent sc) {
none()
}

DataFlowType getSinkNodeType(Input::SinkBase sink, Impl::Private::SummaryComponent sc) { none() }
}

private module StepsInput implements Impl::Private::StepsInputSig {
DataFlowCall getACall(Public::SummarizedCallable sc) {
sc = viableCallable(result).asSummarizedCallable()
}

Node getSourceNode(Input::SourceBase source, Impl::Private::SummaryComponent sc) { none() }

Node getSinkNode(Input::SinkBase sink, Impl::Private::SummaryComponent sc) { none() }
}

private predicate relatedArgSpec(Callable c, string spec) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,14 @@ private import DataFlowImplSpecific::Private
private import DataFlowImplSpecific::Public

module Input implements InputSig<Location, DataFlowImplSpecific::PythonDataFlow> {
private import codeql.util.Void

class SummarizedCallableBase = string;

class SourceBase = Void;

class SinkBase = Void;

ArgumentPosition callbackSelfParameterPosition() { result.isLambdaSelf() }

ReturnKind getStandardReturnValueKind() { any() }
Expand Down Expand Up @@ -98,6 +104,10 @@ private module StepsInput implements Impl::Private::StepsInputSig {
sc.(LibraryCallable).getACallSimple().asCfgNode()
])
}

Node getSourceNode(Input::SourceBase source, Impl::Private::SummaryComponent sc) { none() }

Node getSinkNode(Input::SinkBase sink, Impl::Private::SummaryComponent sc) { none() }
}

module Private {
Expand Down
10 changes: 10 additions & 0 deletions ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,14 @@ private import DataFlowImplSpecific::Private
private import DataFlowImplSpecific::Public

module Input implements InputSig<Location, DataFlowImplSpecific::RubyDataFlow> {
private import codeql.util.Void

class SummarizedCallableBase = string;

class SourceBase = Void;

class SinkBase = Void;

ArgumentPosition callbackSelfParameterPosition() { result.isLambdaSelf() }

ReturnKind getStandardReturnValueKind() { result instanceof NormalReturnKind }
Expand Down Expand Up @@ -154,6 +160,10 @@ private module StepsInput implements Impl::Private::StepsInputSig {
or
result.asCall().getAstNode() = sc.(LibraryCallable).getACallSimple()
}

Node getSourceNode(Input::SourceBase source, Impl::Private::SummaryComponent sc) { none() }

Node getSinkNode(Input::SinkBase sink, Impl::Private::SummaryComponent sc) { none() }
}

module Private {
Expand Down
36 changes: 36 additions & 0 deletions rust/ql/lib/codeql/rust/dataflow/FlowSink.qll
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/** Provides classes and predicates for defining flow sinks. */

private import rust
private import internal.FlowSummaryImpl as Impl
private import internal.DataFlowImpl as DataFlowImpl

// import all instances below
private module Sinks {
private import codeql.rust.Frameworks
private import codeql.rust.dataflow.internal.ModelsAsData
}

/** Provides the `Range` class used to define the extent of `FlowSink`. */
module FlowSink {
/** A flow source. */
abstract class Range extends Impl::Public::SinkNode {
bindingset[this]
Range() { any() }

override predicate isSink(
string input, string kind, Impl::Public::Provenance provenance, string model
) {
this.isSink(input, kind) and provenance = "manual" and model = ""
}

/**
* Holds is this element is a flow sink of kind `kind`, where data
* flows in as described by `input`.
*/
predicate isSink(string output, string kind) { none() }
}
}

final class FlowSink = FlowSink::Range;

predicate sinkNode = DataFlowImpl::sinkNode/2;
36 changes: 36 additions & 0 deletions rust/ql/lib/codeql/rust/dataflow/FlowSource.qll
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/** Provides classes and predicates for defining flow sources. */

private import rust
private import internal.FlowSummaryImpl as Impl
private import internal.DataFlowImpl as DataFlowImpl

// import all instances below
private module Sources {
private import codeql.rust.Frameworks
private import codeql.rust.dataflow.internal.ModelsAsData
}

/** Provides the `Range` class used to define the extent of `FlowSource`. */
module FlowSource {
/** A flow source. */
abstract class Range extends Impl::Public::SourceNode {
bindingset[this]
Range() { any() }

override predicate isSource(
string output, string kind, Impl::Public::Provenance provenance, string model
) {
this.isSource(output, kind) and provenance = "manual" and model = ""
}

/**
* Holds is this element is a flow source of kind `kind`, where data
* flows out as described by `output`.
*/
predicate isSource(string output, string kind) { none() }
}
}

final class FlowSource = FlowSource::Range;

predicate sourceNode = DataFlowImpl::sourceNode/2;
2 changes: 2 additions & 0 deletions rust/ql/lib/codeql/rust/dataflow/FlowSummary.qll
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,5 @@ module SummarizedCallable {
}

final class SummarizedCallable = SummarizedCallable::Range;

final class Provenance = Impl::Public::Provenance;
Loading
Loading