11private import rust
22private import codeql.dataflow.TaintTracking
33private import codeql.rust.controlflow.CfgNodes
4- private import DataFlowImpl
54private import codeql.rust.dataflow.FlowSummary
6- private import FlowSummaryImpl as FlowSummaryImpl
75private import DataFlowImpl
6+ private import FlowSummaryImpl as FlowSummaryImpl
87
98module RustTaintTracking implements InputSig< Location , RustDataFlow > {
109 predicate defaultTaintSanitizer ( Node:: Node node ) { none ( ) }
@@ -35,6 +34,15 @@ module RustTaintTracking implements InputSig<Location, RustDataFlow> {
3534 pred .asExpr ( ) = index .getBase ( ) and
3635 succ .asExpr ( ) = index
3736 )
37+ or
38+ // Although data flow through collections is modeled using stores/reads,
39+ // we also allow taint to flow out of a tainted collection. This is
40+ // needed in order to support taint-tracking configurations where the
41+ // source is a collection.
42+ exists ( ContentSet cs |
43+ RustDataFlow:: readStep ( pred , cs , succ ) and
44+ cs .( SingletonContentSet ) .getContent ( ) instanceof ArrayElementContent
45+ )
3846 )
3947 or
4048 FlowSummaryImpl:: Private:: Steps:: summaryLocalStep ( pred .( Node:: FlowSummaryNode ) .getSummaryNode ( ) ,
@@ -46,7 +54,10 @@ module RustTaintTracking implements InputSig<Location, RustDataFlow> {
4654 * and inputs to additional taint steps.
4755 */
4856 bindingset [ node]
49- predicate defaultImplicitTaintRead ( Node:: Node node , ContentSet c ) { none ( ) }
57+ predicate defaultImplicitTaintRead ( Node:: Node node , ContentSet cs ) {
58+ exists ( node ) and
59+ cs .( SingletonContentSet ) .getContent ( ) instanceof ArrayElementContent
60+ }
5061
5162 /**
5263 * Holds if the additional step from `src` to `sink` should be considered in
0 commit comments