Skip to content

Commit 5144f66

Browse files
committed
Rust: Lift content reads as taint steps
1 parent 1c8cc39 commit 5144f66

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() }
@@ -40,11 +43,22 @@ module RustTaintTracking implements InputSig<Location, RustDataFlow> {
4043
succ.asExpr() = index
4144
)
4245
or
43-
// Although data flow through collections and references is modeled using
44-
// stores/reads, we also allow taint to flow out of a tainted collection
45-
// or reference.
46-
// This is needed in order to support taint-tracking configurations where
47-
// the source is a collection or reference.
46+
// Read steps give rise to taint steps. This has the effect that if `foo`
47+
// is tainted and an operation reads from `foo` (e.g., `foo.bar`) then
48+
// taint is propagated. We limit this to not apply if the type of the
49+
// operation is a small primitive type as these are often uninteresting
50+
// (for instance in the case of an injection query).
51+
RustDataFlow::readContentStep(pred, _, succ) and
52+
not exists(Struct s |
53+
s = TypeInference::inferType(succ.asExpr()).(Type::StructType).getStruct()
54+
|
55+
s instanceof Builtins::NumericType or
56+
s instanceof Builtins::Bool or
57+
s instanceof Builtins::Char
58+
)
59+
or
60+
// Let all read steps (including those from flow summaries and those that
61+
// result in small primitive types) give rise to taint steps.
4862
exists(SingletonContentSet cs | RustDataFlow::readStep(pred, cs, succ) |
4963
cs.getContent() instanceof ElementContent
5064
or

0 commit comments

Comments
 (0)