Rust: Add default taint flow steps

This commit is contained in:
Simon Friis Vindum
2024-12-04 13:30:39 +01:00
parent 70a296be89
commit 3004639fca
6 changed files with 62 additions and 6 deletions

View File

@@ -1,15 +1,45 @@
private import rust
private import codeql.dataflow.TaintTracking
private import codeql.rust.controlflow.CfgNodes
private import DataFlowImpl
private import codeql.rust.dataflow.FlowSummary
private import FlowSummaryImpl as FlowSummaryImpl
private import DataFlowImpl
module RustTaintTracking implements InputSig<Location, RustDataFlow> {
predicate defaultTaintSanitizer(Node::Node node) { none() }
/**
* Holds if the additional step from `src` to `sink` should be included in all
* Holds if the additional step from `pred` to `succ` should be included in all
* global taint flow configurations.
*/
predicate defaultAdditionalTaintStep(Node::Node src, Node::Node sink, string model) { none() }
predicate defaultAdditionalTaintStep(Node::Node pred, Node::Node succ, string model) {
model = "" and
(
exists(BinaryExprCfgNode binary |
binary.getOperatorName() = ["+", "-", "*", "/", "%", "&", "|", "^", "<<", ">>"] and
pred.asExpr() = [binary.getLhs(), binary.getRhs()] and
succ.asExpr() = binary
)
or
exists(PrefixExprCfgNode prefix |
prefix.getOperatorName() = ["-", "!"] and
pred.asExpr() = prefix.getExpr() and
succ.asExpr() = prefix
)
or
pred.asExpr() = succ.asExpr().(CastExprCfgNode).getExpr()
or
exists(IndexExprCfgNode index |
index.getIndex() instanceof RangeExprCfgNode and
pred.asExpr() = index.getBase() and
succ.asExpr() = index
)
)
or
FlowSummaryImpl::Private::Steps::summaryLocalStep(pred.(Node::FlowSummaryNode).getSummaryNode(),
succ.(Node::FlowSummaryNode).getSummaryNode(), false, model)
}
/**
* Holds if taint flow configurations should allow implicit reads of `c` at sinks

View File

@@ -23,7 +23,7 @@ fn coerce(_i: i64) -> i64 {
fn test_coerce() {
let s = source(14);
sink(coerce(s)); // $ MISSING: hasTaintFlow=14
sink(coerce(s)); // $ hasTaintFlow=14
}
enum MyPosEnum {

View File

@@ -4,6 +4,8 @@ edges
| main.rs:15:13:15:21 | source(...) | main.rs:16:19:16:19 | s | provenance | |
| main.rs:16:19:16:19 | s | main.rs:16:10:16:20 | identity(...) | provenance | |
| main.rs:16:19:16:19 | s | main.rs:16:10:16:20 | identity(...) | provenance | |
| main.rs:25:13:25:22 | source(...) | main.rs:26:17:26:17 | s | provenance | |
| main.rs:26:17:26:17 | s | main.rs:26:10:26:18 | coerce(...) | provenance | |
| main.rs:40:13:40:21 | source(...) | main.rs:41:27:41:27 | s | provenance | |
| main.rs:40:13:40:21 | source(...) | main.rs:41:27:41:27 | s | provenance | |
| main.rs:41:14:41:28 | ...::A(...) [A] | main.rs:42:22:42:23 | e1 [A] | provenance | |
@@ -47,6 +49,9 @@ nodes
| main.rs:16:10:16:20 | identity(...) | semmle.label | identity(...) |
| main.rs:16:19:16:19 | s | semmle.label | s |
| main.rs:16:19:16:19 | s | semmle.label | s |
| main.rs:25:13:25:22 | source(...) | semmle.label | source(...) |
| main.rs:26:10:26:18 | coerce(...) | semmle.label | coerce(...) |
| main.rs:26:17:26:17 | s | semmle.label | s |
| main.rs:40:13:40:21 | source(...) | semmle.label | source(...) |
| main.rs:40:13:40:21 | source(...) | semmle.label | source(...) |
| main.rs:41:14:41:28 | ...::A(...) [A] | semmle.label | ...::A(...) [A] |
@@ -97,6 +102,7 @@ invalidSpecComponent
#select
| main.rs:16:10:16:20 | identity(...) | main.rs:15:13:15:21 | source(...) | main.rs:16:10:16:20 | identity(...) | $@ | main.rs:15:13:15:21 | source(...) | source(...) |
| main.rs:16:10:16:20 | identity(...) | main.rs:15:13:15:21 | source(...) | main.rs:16:10:16:20 | identity(...) | $@ | main.rs:15:13:15:21 | source(...) | source(...) |
| main.rs:26:10:26:18 | coerce(...) | main.rs:25:13:25:22 | source(...) | main.rs:26:10:26:18 | coerce(...) | $@ | main.rs:25:13:25:22 | source(...) | source(...) |
| main.rs:42:10:42:24 | get_var_pos(...) | main.rs:40:13:40:21 | source(...) | main.rs:42:10:42:24 | get_var_pos(...) | $@ | main.rs:40:13:40:21 | source(...) | source(...) |
| main.rs:42:10:42:24 | get_var_pos(...) | main.rs:40:13:40:21 | source(...) | main.rs:42:10:42:24 | get_var_pos(...) | $@ | main.rs:40:13:40:21 | source(...) | source(...) |
| main.rs:57:33:57:33 | i | main.rs:53:13:53:21 | source(...) | main.rs:57:33:57:33 | i | $@ | main.rs:53:13:53:21 | source(...) | source(...) |

View File

@@ -0,0 +1,8 @@
| main.rs:4:5:4:8 | 1000 | main.rs:4:5:4:12 | ... + ... | |
| main.rs:4:12:4:12 | i | main.rs:4:5:4:12 | ... + ... | |
| main.rs:13:10:13:10 | a | main.rs:13:10:13:14 | ... + ... | |
| main.rs:13:14:13:14 | 1 | main.rs:13:10:13:14 | ... + ... | |
| main.rs:18:11:18:11 | a | main.rs:18:10:18:11 | - ... | |
| main.rs:23:13:23:13 | a | main.rs:23:13:23:19 | a as u8 | |
| main.rs:24:10:24:10 | b | main.rs:24:10:24:17 | b as i64 | |
| main.rs:38:23:38:23 | s | main.rs:38:23:38:29 | s[...] | |

View File

@@ -1,6 +1,18 @@
models
edges
| main.rs:12:13:12:22 | source(...) | main.rs:13:10:13:14 | ... + ... | provenance | |
| main.rs:17:13:17:22 | source(...) | main.rs:18:10:18:11 | - ... | provenance | |
| main.rs:22:13:22:22 | source(...) | main.rs:24:10:24:17 | b as i64 | provenance | |
nodes
| main.rs:12:13:12:22 | source(...) | semmle.label | source(...) |
| main.rs:13:10:13:14 | ... + ... | semmle.label | ... + ... |
| main.rs:17:13:17:22 | source(...) | semmle.label | source(...) |
| main.rs:18:10:18:11 | - ... | semmle.label | - ... |
| main.rs:22:13:22:22 | source(...) | semmle.label | source(...) |
| main.rs:24:10:24:17 | b as i64 | semmle.label | b as i64 |
subpaths
testFailures
#select
| main.rs:13:10:13:14 | ... + ... | main.rs:12:13:12:22 | source(...) | main.rs:13:10:13:14 | ... + ... | $@ | main.rs:12:13:12:22 | source(...) | source(...) |
| main.rs:18:10:18:11 | - ... | main.rs:17:13:17:22 | source(...) | main.rs:18:10:18:11 | - ... | $@ | main.rs:17:13:17:22 | source(...) | source(...) |
| main.rs:24:10:24:17 | b as i64 | main.rs:22:13:22:22 | source(...) | main.rs:24:10:24:17 | b as i64 | $@ | main.rs:22:13:22:22 | source(...) | source(...) |

View File

@@ -10,18 +10,18 @@ fn sink(s: i64) {
fn addition() {
let a = source(42);
sink(a + 1); // $ MISSING: hasTaintFlow=42
sink(a + 1); // $ hasTaintFlow=42
}
fn negation() {
let a = source(17);
sink(-a); // $ MISSING: hasTaintFlow=17
sink(-a); // $ hasTaintFlow=17
}
fn cast() {
let a = source(77);
let b = a as u8;
sink(b as i64); // $ MISSING: hasTaintFlow=77
sink(b as i64); // $ hasTaintFlow=77
}
mod string {