Skip to content

Commit aab3428

Browse files
committed
Rust: Model address-of and dereference as stores and loads
1 parent df03751 commit aab3428

File tree

14 files changed

+97
-18
lines changed

14 files changed

+97
-18
lines changed

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

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -712,6 +712,11 @@ private class CapturedVariableContent extends Content, TCapturedVariableContent
712712
override string toString() { result = "captured " + v }
713713
}
714714

715+
/** A value refered to by a reference. */
716+
final class ReferenceContent extends Content, TReferenceContent {
717+
override string toString() { result = "&ref" }
718+
}
719+
715720
/**
716721
* An element in an array.
717722
*/
@@ -1040,6 +1045,13 @@ module RustDataFlow implements InputSig<Location> {
10401045
["crate::option::Option::Some", "crate::result::Result::Ok"]
10411046
)
10421047
or
1048+
exists(PrefixExprCfgNode deref |
1049+
c instanceof ReferenceContent and
1050+
deref.getOperatorName() = "*" and
1051+
node1.asExpr() = deref.getExpr() and
1052+
node2.asExpr() = deref
1053+
)
1054+
or
10431055
VariableCapture::readStep(node1, c, node2)
10441056
)
10451057
or
@@ -1123,6 +1135,12 @@ module RustDataFlow implements InputSig<Location> {
11231135
node2.(PostUpdateNode).getPreUpdateNode().asExpr() = index.getBase()
11241136
)
11251137
or
1138+
exists(RefExprCfgNode ref |
1139+
c instanceof ReferenceContent and
1140+
node1.asExpr() = ref.getExpr() and
1141+
node2.asExpr() = ref
1142+
)
1143+
or
11261144
VariableCapture::storeStep(node1, c, node2)
11271145
)
11281146
or
@@ -1382,7 +1400,8 @@ private module Cached {
13821400
e =
13831401
[
13841402
any(IndexExprCfgNode i).getBase(), any(FieldExprCfgNode access).getExpr(),
1385-
any(TryExprCfgNode try).getExpr()
1403+
any(TryExprCfgNode try).getExpr(),
1404+
any(PrefixExprCfgNode pe | pe.getOperatorName() = "*").getExpr()
13861405
]
13871406
} or
13881407
TSsaNode(SsaImpl::DataFlowIntegration::SsaNode node) or
@@ -1482,7 +1501,8 @@ private module Cached {
14821501
TStructFieldContent(StructCanonicalPath s, string field) {
14831502
field = s.getStruct().getFieldList().(RecordFieldList).getAField().getName().getText()
14841503
} or
1485-
TCapturedVariableContent(VariableCapture::CapturedVariable v)
1504+
TCapturedVariableContent(VariableCapture::CapturedVariable v) or
1505+
TReferenceContent()
14861506

14871507
cached
14881508
newtype TContentSet = TSingletonContentSet(Content c)

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ module RustTaintTracking implements InputSig<Location, RustDataFlow> {
4646
RustDataFlow::readStep(pred, cs, succ) and
4747
cs.getContent() instanceof ArrayElementContent
4848
)
49+
or
50+
pred.asExpr() = succ.asExpr().(RefExprCfgNode).getExpr()
4951
)
5052
or
5153
FlowSummaryImpl::Private::Steps::summaryLocalStep(pred.(Node::FlowSummaryNode).getSummaryNode(),
@@ -59,7 +61,10 @@ module RustTaintTracking implements InputSig<Location, RustDataFlow> {
5961
bindingset[node]
6062
predicate defaultImplicitTaintRead(Node::Node node, ContentSet cs) {
6163
exists(node) and
62-
cs.(SingletonContentSet).getContent() instanceof ArrayElementContent
64+
exists(Content c | c = cs.(SingletonContentSet).getContent() |
65+
c instanceof ArrayElementContent or
66+
c instanceof ReferenceContent
67+
)
6368
}
6469

6570
/**

rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,6 @@ module Impl {
484484
class VariableReadAccess extends VariableAccess {
485485
VariableReadAccess() {
486486
not this instanceof VariableWriteAccess and
487-
not this = any(RefExpr re).getExpr() and
488487
not this = any(CompoundAssignmentExpr cae).getLhs()
489488
}
490489
}

rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,7 @@ storeStep
530530
readStep
531531
| file://:0:0:0:0 | [summary param] self in lang:core::_::<crate::option::Option>::unwrap | Some | file://:0:0:0:0 | [summary] read: Argument[self].Variant[crate::option::Option::Some(0)] in lang:core::_::<crate::option::Option>::unwrap |
532532
| main.rs:33:9:33:15 | Some(...) | Some | main.rs:33:14:33:14 | _ |
533+
| main.rs:87:11:87:11 | i | &ref | main.rs:87:10:87:11 | * ... |
533534
| main.rs:95:10:95:10 | a | tuple.0 | main.rs:95:10:95:12 | a.0 |
534535
| main.rs:96:10:96:10 | a | tuple.1 | main.rs:96:10:96:12 | a.1 |
535536
| main.rs:109:10:109:10 | a | tuple.0 | main.rs:109:10:109:12 | a.0 |

rust/ql/test/library-tests/dataflow/pointers/inline-flow.expected

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
models
22
edges
3+
| main.rs:13:13:13:22 | source(...) | main.rs:14:14:14:14 | a | provenance | |
4+
| main.rs:14:13:14:14 | &a [&ref] | main.rs:15:14:15:14 | b [&ref] | provenance | |
5+
| main.rs:14:14:14:14 | a | main.rs:14:13:14:14 | &a [&ref] | provenance | |
6+
| main.rs:15:13:15:14 | * ... | main.rs:16:10:16:10 | c | provenance | |
7+
| main.rs:15:14:15:14 | b [&ref] | main.rs:15:13:15:14 | * ... | provenance | |
38
| main.rs:40:18:40:21 | SelfParam [MyNumber] | main.rs:42:13:42:38 | ...::MyNumber(...) [MyNumber] | provenance | |
49
| main.rs:42:13:42:38 | ...::MyNumber(...) [MyNumber] | main.rs:42:32:42:37 | number | provenance | |
510
| main.rs:42:32:42:37 | number | main.rs:40:31:46:5 | { ... } | provenance | |
@@ -8,6 +13,12 @@ edges
813
| main.rs:59:10:59:18 | my_number [MyNumber] | main.rs:40:18:40:21 | SelfParam [MyNumber] | provenance | |
914
| main.rs:59:10:59:18 | my_number [MyNumber] | main.rs:59:10:59:30 | my_number.to_number(...) | provenance | |
1015
nodes
16+
| main.rs:13:13:13:22 | source(...) | semmle.label | source(...) |
17+
| main.rs:14:13:14:14 | &a [&ref] | semmle.label | &a [&ref] |
18+
| main.rs:14:14:14:14 | a | semmle.label | a |
19+
| main.rs:15:13:15:14 | * ... | semmle.label | * ... |
20+
| main.rs:15:14:15:14 | b [&ref] | semmle.label | b [&ref] |
21+
| main.rs:16:10:16:10 | c | semmle.label | c |
1122
| main.rs:40:18:40:21 | SelfParam [MyNumber] | semmle.label | SelfParam [MyNumber] |
1223
| main.rs:40:31:46:5 | { ... } | semmle.label | { ... } |
1324
| main.rs:42:13:42:38 | ...::MyNumber(...) [MyNumber] | semmle.label | ...::MyNumber(...) [MyNumber] |
@@ -20,4 +31,5 @@ subpaths
2031
| main.rs:59:10:59:18 | my_number [MyNumber] | main.rs:40:18:40:21 | SelfParam [MyNumber] | main.rs:40:31:46:5 | { ... } | main.rs:59:10:59:30 | my_number.to_number(...) |
2132
testFailures
2233
#select
34+
| main.rs:16:10:16:10 | c | main.rs:13:13:13:22 | source(...) | main.rs:16:10:16:10 | c | $@ | main.rs:13:13:13:22 | source(...) | source(...) |
2335
| main.rs:59:10:59:30 | my_number.to_number(...) | main.rs:58:40:58:49 | source(...) | main.rs:59:10:59:30 | my_number.to_number(...) | $@ | main.rs:58:40:58:49 | source(...) | source(...) |

rust/ql/test/library-tests/dataflow/pointers/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ fn read_through_borrow() {
1313
let a = source(21);
1414
let b = &a;
1515
let c = *b;
16-
sink(c); // $ MISSING: hasValueFlow=21
16+
sink(c); // $ hasValueFlow=21
1717
}
1818

1919
fn write_through_borrow() {
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,23 @@
11
models
22
edges
3+
| main.rs:20:13:20:22 | source(...) | main.rs:21:19:21:25 | s[...] | provenance | |
4+
| main.rs:20:13:20:22 | source(...) | main.rs:22:16:22:21 | sliced | provenance | |
5+
| main.rs:21:18:21:25 | &... [&ref] | main.rs:22:16:22:21 | sliced | provenance | |
6+
| main.rs:21:19:21:25 | s[...] | main.rs:21:18:21:25 | &... [&ref] | provenance | |
37
| main.rs:26:14:26:23 | source(...) | main.rs:32:10:32:11 | s4 | provenance | |
8+
| main.rs:37:14:37:23 | source(...) | main.rs:40:10:40:35 | ... + ... | provenance | |
49
nodes
10+
| main.rs:20:13:20:22 | source(...) | semmle.label | source(...) |
11+
| main.rs:21:18:21:25 | &... [&ref] | semmle.label | &... [&ref] |
12+
| main.rs:21:19:21:25 | s[...] | semmle.label | s[...] |
13+
| main.rs:22:16:22:21 | sliced | semmle.label | sliced |
514
| main.rs:26:14:26:23 | source(...) | semmle.label | source(...) |
615
| main.rs:32:10:32:11 | s4 | semmle.label | s4 |
16+
| main.rs:37:14:37:23 | source(...) | semmle.label | source(...) |
17+
| main.rs:40:10:40:35 | ... + ... | semmle.label | ... + ... |
718
subpaths
819
testFailures
920
#select
21+
| main.rs:22:16:22:21 | sliced | main.rs:20:13:20:22 | source(...) | main.rs:22:16:22:21 | sliced | $@ | main.rs:20:13:20:22 | source(...) | source(...) |
1022
| main.rs:32:10:32:11 | s4 | main.rs:26:14:26:23 | source(...) | main.rs:32:10:32:11 | s4 | $@ | main.rs:26:14:26:23 | source(...) | source(...) |
23+
| main.rs:40:10:40:35 | ... + ... | main.rs:37:14:37:23 | source(...) | main.rs:40:10:40:35 | ... + ... | $@ | main.rs:37:14:37:23 | source(...) | source(...) |

rust/ql/test/library-tests/dataflow/strings/main.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ fn sink(s: String) {
1919
fn string_slice() {
2020
let s = source(35);
2121
let sliced = &s[1..3];
22-
sink_slice(sliced); // $ MISSING: hasTaintFlow=35
22+
sink_slice(sliced); // $ hasTaintFlow=35
2323
}
2424

2525
fn string_add() {
@@ -37,7 +37,7 @@ fn string_add_reference() {
3737
let s1 = source(37);
3838
let s2 = "1".to_string();
3939

40-
sink("Hello ".to_string() + &s1); // $ MISSING: hasTaintFlow=37
40+
sink("Hello ".to_string() + &s1); // $ hasTaintFlow=37
4141
sink("Hello ".to_string() + &s2);
4242
}
4343

rust/ql/test/library-tests/dataflow/taint/TaintFlowStep.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
| main.rs:23:13:23:13 | a | main.rs:23:13:23:19 | a as u8 | |
77
| main.rs:24:10:24:10 | b | main.rs:24:10:24:17 | b as i64 | |
88
| main.rs:38:23:38:23 | s | main.rs:38:23:38:29 | s[...] | |
9+
| main.rs:38:23:38:29 | s[...] | main.rs:38:22:38:29 | &... | |
910
| main.rs:54:14:54:16 | arr | main.rs:54:14:54:19 | arr[1] | |
1011
| main.rs:64:24:64:24 | s | main.rs:64:24:64:27 | s[1] | |
1112
| main.rs:69:9:69:12 | arr2 | main.rs:69:9:69:15 | arr2[1] | |

rust/ql/test/library-tests/dataflow/taint/inline-taint-flow.expected

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ edges
33
| main.rs:12:13:12:22 | source(...) | main.rs:13:10:13:14 | ... + ... | provenance | |
44
| main.rs:17:13:17:22 | source(...) | main.rs:18:10:18:11 | - ... | provenance | |
55
| main.rs:22:13:22:22 | source(...) | main.rs:24:10:24:17 | b as i64 | provenance | |
6+
| main.rs:37:17:37:26 | source(...) | main.rs:38:23:38:29 | s[...] | provenance | |
7+
| main.rs:37:17:37:26 | source(...) | main.rs:39:14:39:19 | sliced | provenance | |
8+
| main.rs:38:22:38:29 | &... [&ref] | main.rs:39:14:39:19 | sliced | provenance | |
9+
| main.rs:38:23:38:29 | s[...] | main.rs:38:22:38:29 | &... [&ref] | provenance | |
610
| main.rs:53:19:53:28 | source(...) | main.rs:54:14:54:19 | arr[1] | provenance | |
711
| main.rs:69:9:69:12 | [post] arr2 [array[]] | main.rs:70:14:70:17 | arr2 | provenance | |
812
| main.rs:69:19:69:28 | source(...) | main.rs:69:9:69:12 | [post] arr2 [array[]] | provenance | |
@@ -13,6 +17,10 @@ nodes
1317
| main.rs:18:10:18:11 | - ... | semmle.label | - ... |
1418
| main.rs:22:13:22:22 | source(...) | semmle.label | source(...) |
1519
| main.rs:24:10:24:17 | b as i64 | semmle.label | b as i64 |
20+
| main.rs:37:17:37:26 | source(...) | semmle.label | source(...) |
21+
| main.rs:38:22:38:29 | &... [&ref] | semmle.label | &... [&ref] |
22+
| main.rs:38:23:38:29 | s[...] | semmle.label | s[...] |
23+
| main.rs:39:14:39:19 | sliced | semmle.label | sliced |
1624
| main.rs:53:19:53:28 | source(...) | semmle.label | source(...) |
1725
| main.rs:54:14:54:19 | arr[1] | semmle.label | arr[1] |
1826
| main.rs:69:9:69:12 | [post] arr2 [array[]] | semmle.label | [post] arr2 [array[]] |
@@ -24,5 +32,6 @@ testFailures
2432
| 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(...) |
2533
| 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(...) |
2634
| 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(...) |
35+
| main.rs:39:14:39:19 | sliced | main.rs:37:17:37:26 | source(...) | main.rs:39:14:39:19 | sliced | $@ | main.rs:37:17:37:26 | source(...) | source(...) |
2736
| main.rs:54:14:54:19 | arr[1] | main.rs:53:19:53:28 | source(...) | main.rs:54:14:54:19 | arr[1] | $@ | main.rs:53:19:53:28 | source(...) | source(...) |
2837
| main.rs:70:14:70:17 | arr2 | main.rs:69:19:69:28 | source(...) | main.rs:70:14:70:17 | arr2 | $@ | main.rs:69:19:69:28 | source(...) | source(...) |

0 commit comments

Comments
 (0)