Skip to content

Commit 8a0e5b5

Browse files
committed
Rust: Lift content reads as taint steps
1 parent cd721b8 commit 8a0e5b5

File tree

1 file changed

+19
-5
lines changed

1 file changed

+19
-5
lines changed

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

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ private import Node as Node
77
private import Content
88
private import FlowSummaryImpl as FlowSummaryImpl
99
private import codeql.rust.internal.CachedStages
10+
private import codeql.rust.internal.TypeInference as TypeInference
11+
private import codeql.rust.internal.Type as Type
12+
private import codeql.rust.frameworks.stdlib.Builtins as Builtins
1013

1114
module RustTaintTracking implements InputSig<Location, RustDataFlow> {
1215
predicate defaultTaintSanitizer(DataFlow::Node node) { none() }
@@ -28,11 +31,22 @@ module RustTaintTracking implements InputSig<Location, RustDataFlow> {
2831
succ.asExpr() = index
2932
)
3033
or
31-
// Although data flow through collections and references is modeled using
32-
// stores/reads, we also allow taint to flow out of a tainted collection
33-
// or reference.
34-
// This is needed in order to support taint-tracking configurations where
35-
// the source is a collection or reference.
34+
// Read steps give rise to taint steps. This has the effect that if `foo`
35+
// is tainted and an operation reads from `foo` (e.g., `foo.bar`) then
36+
// taint is propagated. We limit this to not apply if the type of the
37+
// operation is a small primitive type as these are often uninteresting
38+
// (for instance in the case of an injection query).
39+
RustDataFlow::readContentStep(pred, _, succ) and
40+
not exists(Struct s |
41+
s = TypeInference::inferType(succ.asExpr()).(Type::StructType).getStruct()
42+
|
43+
s instanceof Builtins::NumericType or
44+
s instanceof Builtins::Bool or
45+
s instanceof Builtins::Char
46+
)
47+
or
48+
// Let all read steps (including those from flow summaries and those that
49+
// result in small primitive types) give rise to taint steps.
3650
exists(SingletonContentSet cs | RustDataFlow::readStep(pred, cs, succ) |
3751
cs.getContent() instanceof ElementContent
3852
or

0 commit comments

Comments
 (0)