mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
Merge pull request #20340 from hvitved/rust/taint-tracking-implicit-deref-at-sinks
Rust: Deref as taint step
This commit is contained in:
@@ -41,13 +41,15 @@ module RustTaintTracking implements InputSig<Location, RustDataFlow> {
|
||||
succ.asExpr() = index
|
||||
)
|
||||
or
|
||||
// Although data flow through collections is modeled using stores/reads,
|
||||
// we also allow taint to flow out of a tainted collection. This is
|
||||
// needed in order to support taint-tracking configurations where the
|
||||
// source is a collection.
|
||||
exists(SingletonContentSet cs |
|
||||
RustDataFlow::readStep(pred, cs, succ) and
|
||||
// Although data flow through collections and references is modeled using
|
||||
// stores/reads, we also allow taint to flow out of a tainted collection
|
||||
// or reference.
|
||||
// This is needed in order to support taint-tracking configurations where
|
||||
// the source is a collection or reference.
|
||||
exists(SingletonContentSet cs | RustDataFlow::readStep(pred, cs, succ) |
|
||||
cs.getContent() instanceof ElementContent
|
||||
or
|
||||
cs.getContent() instanceof ReferenceContent
|
||||
)
|
||||
or
|
||||
exists(FormatArgsExprCfgNode format | succ.asExpr() = format |
|
||||
|
||||
@@ -39,12 +39,6 @@ module HardcodedCryptographicValueConfig implements DataFlow::ConfigSig {
|
||||
// case like `[0, 0, 0, 0]`)
|
||||
isSource(node)
|
||||
}
|
||||
|
||||
predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) {
|
||||
// flow out from reference content at sinks.
|
||||
isSink(node) and
|
||||
c.getAReadContent() instanceof ReferenceContent
|
||||
}
|
||||
}
|
||||
|
||||
module HardcodedCryptographicValueFlow = TaintTracking::Global<HardcodedCryptographicValueConfig>;
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
models
|
||||
| 1 | Summary: <alloc::string::String as core::convert::From>::from; Argument[0]; ReturnValue; value |
|
||||
| 2 | Summary: <alloc::string::String as core::ops::arith::Add>::add; Argument[self]; ReturnValue; value |
|
||||
| 3 | Summary: <alloc::string::String>::as_str; Argument[self]; ReturnValue; value |
|
||||
| 4 | Summary: <core::str>::as_str; Argument[self]; ReturnValue; value |
|
||||
| 5 | Summary: alloc::fmt::format; Argument[0]; ReturnValue; taint |
|
||||
| 6 | Summary: core::hint::must_use; Argument[0]; ReturnValue; value |
|
||||
| 1 | Summary: <alloc::string::String as core::convert::From>::from; Argument[0].Reference; ReturnValue; value |
|
||||
| 2 | Summary: <alloc::string::String as core::convert::From>::from; Argument[0]; ReturnValue; value |
|
||||
| 3 | Summary: <alloc::string::String as core::ops::arith::Add>::add; Argument[self]; ReturnValue; value |
|
||||
| 4 | Summary: <alloc::string::String>::as_str; Argument[self]; ReturnValue; value |
|
||||
| 5 | Summary: <core::str>::as_str; Argument[self]; ReturnValue; value |
|
||||
| 6 | Summary: alloc::fmt::format; Argument[0]; ReturnValue; taint |
|
||||
| 7 | Summary: core::hint::must_use; Argument[0]; ReturnValue; value |
|
||||
edges
|
||||
| main.rs:26:9:26:9 | s | main.rs:27:19:27:25 | s[...] | provenance | |
|
||||
| main.rs:26:13:26:22 | source(...) | main.rs:26:9:26:9 | s | provenance | |
|
||||
@@ -15,46 +16,47 @@ edges
|
||||
| main.rs:32:9:32:10 | s1 | main.rs:35:14:35:15 | s1 | provenance | |
|
||||
| main.rs:32:14:32:23 | source(...) | main.rs:32:9:32:10 | s1 | provenance | |
|
||||
| main.rs:35:9:35:10 | s4 | main.rs:38:10:38:11 | s4 | provenance | |
|
||||
| main.rs:35:14:35:15 | s1 | main.rs:35:14:35:20 | ... + ... | provenance | MaD:2 |
|
||||
| main.rs:35:14:35:15 | s1 | main.rs:35:14:35:20 | ... + ... | provenance | MaD:3 |
|
||||
| main.rs:35:14:35:20 | ... + ... | main.rs:35:9:35:10 | s4 | provenance | |
|
||||
| main.rs:51:9:51:10 | s1 | main.rs:52:27:52:28 | s1 | provenance | |
|
||||
| main.rs:51:14:51:29 | source_slice(...) | main.rs:51:9:51:10 | s1 | provenance | |
|
||||
| main.rs:52:9:52:10 | s2 | main.rs:53:10:53:11 | s2 | provenance | |
|
||||
| main.rs:52:14:52:29 | ...::from(...) | main.rs:52:9:52:10 | s2 | provenance | |
|
||||
| main.rs:52:27:52:28 | s1 | main.rs:52:14:52:29 | ...::from(...) | provenance | MaD:1 |
|
||||
| main.rs:52:27:52:28 | s1 | main.rs:52:14:52:29 | ...::from(...) | provenance | MaD:2 |
|
||||
| main.rs:63:9:63:9 | s | main.rs:64:16:64:16 | s | provenance | |
|
||||
| main.rs:63:9:63:9 | s | main.rs:64:16:64:25 | s.as_str() | provenance | MaD:3 |
|
||||
| main.rs:63:9:63:9 | s | main.rs:64:16:64:25 | s.as_str() | provenance | MaD:4 |
|
||||
| main.rs:63:9:63:9 | s | main.rs:64:16:64:25 | s.as_str() | provenance | MaD:5 |
|
||||
| main.rs:63:13:63:22 | source(...) | main.rs:63:9:63:9 | s | provenance | |
|
||||
| main.rs:64:16:64:16 | s | main.rs:64:16:64:25 | s.as_str() | provenance | MaD:3 |
|
||||
| main.rs:64:16:64:16 | s | main.rs:64:16:64:25 | s.as_str() | provenance | MaD:4 |
|
||||
| main.rs:64:16:64:16 | s | main.rs:64:16:64:25 | s.as_str() | provenance | MaD:5 |
|
||||
| main.rs:68:9:68:9 | s | main.rs:70:34:70:61 | MacroExpr | provenance | |
|
||||
| main.rs:68:9:68:9 | s | main.rs:73:34:73:59 | MacroExpr | provenance | |
|
||||
| main.rs:68:13:68:22 | source(...) | main.rs:68:9:68:9 | s | provenance | |
|
||||
| main.rs:70:9:70:18 | formatted1 | main.rs:71:10:71:19 | formatted1 | provenance | |
|
||||
| main.rs:70:22:70:62 | ...::format(...) | main.rs:70:9:70:18 | formatted1 | provenance | |
|
||||
| main.rs:70:34:70:61 | MacroExpr | main.rs:70:22:70:62 | ...::format(...) | provenance | MaD:5 |
|
||||
| main.rs:70:34:70:61 | MacroExpr | main.rs:70:22:70:62 | ...::format(...) | provenance | MaD:6 |
|
||||
| main.rs:73:9:73:18 | formatted2 | main.rs:74:10:74:19 | formatted2 | provenance | |
|
||||
| main.rs:73:22:73:60 | ...::format(...) | main.rs:73:9:73:18 | formatted2 | provenance | |
|
||||
| main.rs:73:34:73:59 | MacroExpr | main.rs:73:22:73:60 | ...::format(...) | provenance | MaD:5 |
|
||||
| main.rs:73:34:73:59 | MacroExpr | main.rs:73:22:73:60 | ...::format(...) | provenance | MaD:6 |
|
||||
| main.rs:76:9:76:13 | width | main.rs:77:34:77:74 | MacroExpr | provenance | |
|
||||
| main.rs:76:17:76:32 | source_usize(...) | main.rs:76:9:76:13 | width | provenance | |
|
||||
| main.rs:77:9:77:18 | formatted3 | main.rs:78:10:78:19 | formatted3 | provenance | |
|
||||
| main.rs:77:22:77:75 | ...::format(...) | main.rs:77:9:77:18 | formatted3 | provenance | |
|
||||
| main.rs:77:34:77:74 | MacroExpr | main.rs:77:22:77:75 | ...::format(...) | provenance | MaD:5 |
|
||||
| main.rs:77:34:77:74 | MacroExpr | main.rs:77:22:77:75 | ...::format(...) | provenance | MaD:6 |
|
||||
| main.rs:82:9:82:10 | s1 | main.rs:86:18:86:25 | MacroExpr | provenance | |
|
||||
| main.rs:82:9:82:10 | s1 | main.rs:87:18:87:32 | MacroExpr | provenance | |
|
||||
| main.rs:82:14:82:23 | source(...) | main.rs:82:9:82:10 | s1 | provenance | |
|
||||
| main.rs:86:10:86:16 | res | main.rs:86:18:86:25 | { ... } | provenance | |
|
||||
| main.rs:86:18:86:25 | ...::format(...) | main.rs:86:10:86:16 | res | provenance | |
|
||||
| main.rs:86:18:86:25 | ...::must_use(...) | main.rs:86:10:86:26 | MacroExpr | provenance | |
|
||||
| main.rs:86:18:86:25 | MacroExpr | main.rs:86:18:86:25 | ...::format(...) | provenance | MaD:5 |
|
||||
| main.rs:86:18:86:25 | { ... } | main.rs:86:18:86:25 | ...::must_use(...) | provenance | MaD:6 |
|
||||
| main.rs:86:18:86:25 | MacroExpr | main.rs:86:18:86:25 | ...::format(...) | provenance | MaD:6 |
|
||||
| main.rs:86:18:86:25 | { ... } | main.rs:86:18:86:25 | ...::must_use(...) | provenance | MaD:7 |
|
||||
| main.rs:87:10:87:16 | res | main.rs:87:18:87:32 | { ... } | provenance | |
|
||||
| main.rs:87:18:87:32 | ...::format(...) | main.rs:87:10:87:16 | res | provenance | |
|
||||
| main.rs:87:18:87:32 | ...::must_use(...) | main.rs:87:10:87:33 | MacroExpr | provenance | |
|
||||
| main.rs:87:18:87:32 | MacroExpr | main.rs:87:18:87:32 | ...::format(...) | provenance | MaD:5 |
|
||||
| main.rs:87:18:87:32 | { ... } | main.rs:87:18:87:32 | ...::must_use(...) | provenance | MaD:6 |
|
||||
| main.rs:87:18:87:32 | MacroExpr | main.rs:87:18:87:32 | ...::format(...) | provenance | MaD:6 |
|
||||
| main.rs:87:18:87:32 | { ... } | main.rs:87:18:87:32 | ...::must_use(...) | provenance | MaD:7 |
|
||||
nodes
|
||||
| main.rs:26:9:26:9 | s | semmle.label | s |
|
||||
| main.rs:26:13:26:22 | source(...) | semmle.label | source(...) |
|
||||
|
||||
@@ -45,12 +45,18 @@ edges
|
||||
| src/main.rs:98:21:98:53 | ... .unwrap() | src/main.rs:98:9:98:17 | file_path | provenance | |
|
||||
| src/main.rs:99:24:99:32 | file_path | src/main.rs:99:5:99:22 | ...::read_to_string | provenance | MaD:6 Sink:MaD:6 |
|
||||
| src/main.rs:103:9:103:13 | path1 | src/main.rs:104:33:104:37 | path1 | provenance | |
|
||||
| src/main.rs:103:9:103:13 | path1 | src/main.rs:104:33:104:45 | path1.clone() | provenance | MaD:8 |
|
||||
| src/main.rs:103:9:103:13 | path1 | src/main.rs:106:39:106:43 | path1 | provenance | |
|
||||
| src/main.rs:103:9:103:13 | path1 | src/main.rs:106:39:106:51 | path1.clone() | provenance | MaD:8 |
|
||||
| src/main.rs:103:9:103:13 | path1 | src/main.rs:109:41:109:45 | path1 | provenance | |
|
||||
| src/main.rs:103:9:103:13 | path1 | src/main.rs:109:41:109:53 | path1.clone() | provenance | MaD:8 |
|
||||
| src/main.rs:103:9:103:13 | path1 | src/main.rs:112:45:112:49 | path1 | provenance | |
|
||||
| src/main.rs:103:9:103:13 | path1 | src/main.rs:112:45:112:57 | path1.clone() | provenance | MaD:8 |
|
||||
| src/main.rs:103:9:103:13 | path1 | src/main.rs:115:39:115:43 | path1 | provenance | |
|
||||
| src/main.rs:103:9:103:13 | path1 | src/main.rs:122:27:122:31 | path1 | provenance | |
|
||||
| src/main.rs:103:9:103:13 | path1 | src/main.rs:122:27:122:39 | path1.clone() | provenance | MaD:8 |
|
||||
| src/main.rs:103:9:103:13 | path1 | src/main.rs:123:37:123:41 | path1 | provenance | |
|
||||
| src/main.rs:103:9:103:13 | path1 | src/main.rs:123:37:123:49 | path1.clone() | provenance | MaD:8 |
|
||||
| src/main.rs:103:17:103:30 | ...::args | src/main.rs:103:17:103:32 | ...::args(...) [element] | provenance | Src:MaD:7 |
|
||||
| src/main.rs:103:17:103:32 | ...::args(...) [element] | src/main.rs:103:17:103:39 | ... .nth(...) [Some] | provenance | MaD:9 |
|
||||
| src/main.rs:103:17:103:39 | ... .nth(...) [Some] | src/main.rs:103:17:103:48 | ... .unwrap() | provenance | MaD:10 |
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
| lifetime.rs:667:14:667:17 | ref1 | lifetime.rs:655:11:655:25 | &raw const str2 | lifetime.rs:667:14:667:17 | ref1 | Access of a pointer to $@ after its lifetime has ended. | lifetime.rs:651:7:651:10 | str2 | str2 |
|
||||
| lifetime.rs:789:12:789:13 | p1 | lifetime.rs:781:9:781:19 | &my_local10 | lifetime.rs:789:12:789:13 | p1 | Access of a pointer to $@ after its lifetime has ended. | lifetime.rs:779:6:779:15 | my_local10 | my_local10 |
|
||||
| lifetime.rs:808:23:808:25 | ptr | lifetime.rs:798:9:798:12 | &val | lifetime.rs:808:23:808:25 | ptr | Access of a pointer to $@ after its lifetime has ended. | lifetime.rs:796:6:796:8 | val | val |
|
||||
| main.rs:64:23:64:24 | p2 | main.rs:44:26:44:28 | &b2 | main.rs:64:23:64:24 | p2 | Access of a pointer to $@ after its lifetime has ended. | main.rs:43:13:43:14 | b2 | b2 |
|
||||
edges
|
||||
| deallocation.rs:148:6:148:7 | p1 | deallocation.rs:151:14:151:15 | p1 | provenance | |
|
||||
| deallocation.rs:148:6:148:7 | p1 | deallocation.rs:158:14:158:15 | p1 | provenance | |
|
||||
@@ -163,7 +164,7 @@ edges
|
||||
| lifetime.rs:443:6:443:7 | p1 | lifetime.rs:446:13:446:14 | p1 | provenance | |
|
||||
| lifetime.rs:443:6:443:7 | p1 | lifetime.rs:450:2:450:10 | return p1 | provenance | |
|
||||
| lifetime.rs:443:23:443:44 | ...::from_ref(...) | lifetime.rs:443:6:443:7 | p1 | provenance | |
|
||||
| lifetime.rs:443:42:443:43 | r1 | lifetime.rs:443:23:443:44 | ...::from_ref(...) | provenance | MaD:1 |
|
||||
| lifetime.rs:443:42:443:43 | r1 | lifetime.rs:443:23:443:44 | ...::from_ref(...) | provenance | MaD:3 |
|
||||
| lifetime.rs:450:2:450:10 | return p1 | lifetime.rs:454:11:454:29 | get_ptr_from_ref(...) | provenance | |
|
||||
| lifetime.rs:450:2:450:10 | return p1 | lifetime.rs:460:13:460:31 | get_ptr_from_ref(...) | provenance | |
|
||||
| lifetime.rs:454:6:454:7 | p1 | lifetime.rs:459:13:459:14 | p1 | provenance | |
|
||||
@@ -212,8 +213,21 @@ edges
|
||||
| lifetime.rs:798:9:798:12 | &val | lifetime.rs:798:2:798:12 | return ... | provenance | |
|
||||
| lifetime.rs:802:6:802:8 | ptr | lifetime.rs:808:23:808:25 | ptr | provenance | |
|
||||
| lifetime.rs:802:12:802:24 | get_pointer(...) | lifetime.rs:802:6:802:8 | ptr | provenance | |
|
||||
| main.rs:18:9:18:10 | p1 [&ref] | main.rs:21:19:21:20 | p1 | provenance | |
|
||||
| main.rs:18:9:18:10 | p1 [&ref] | main.rs:29:19:29:20 | p1 | provenance | |
|
||||
| main.rs:18:14:18:29 | ...::as_ptr(...) [&ref] | main.rs:18:9:18:10 | p1 [&ref] | provenance | |
|
||||
| main.rs:18:26:18:28 | &b1 | main.rs:18:14:18:29 | ...::as_ptr(...) [&ref] | provenance | MaD:2 |
|
||||
| main.rs:44:9:44:10 | p2 [&ref] | main.rs:51:23:51:24 | p2 | provenance | |
|
||||
| main.rs:44:9:44:10 | p2 [&ref] | main.rs:64:23:64:24 | p2 | provenance | |
|
||||
| main.rs:44:14:44:29 | ...::as_ptr(...) [&ref] | main.rs:44:9:44:10 | p2 [&ref] | provenance | |
|
||||
| main.rs:44:26:44:28 | &b2 | main.rs:44:14:44:29 | ...::as_ptr(...) [&ref] | provenance | MaD:2 |
|
||||
| main.rs:47:9:47:10 | p3 [&ref] | main.rs:52:23:52:24 | p3 | provenance | |
|
||||
| main.rs:47:14:47:37 | ...::as_mut_ptr(...) [&ref] | main.rs:47:9:47:10 | p3 [&ref] | provenance | |
|
||||
| main.rs:47:30:47:36 | &mut b3 | main.rs:47:14:47:37 | ...::as_mut_ptr(...) [&ref] | provenance | MaD:1 |
|
||||
models
|
||||
| 1 | Summary: core::ptr::from_ref; Argument[0]; ReturnValue; value |
|
||||
| 1 | Summary: <alloc::boxed::Box>::as_mut_ptr; Argument[0].Reference.Reference; ReturnValue.Reference; value |
|
||||
| 2 | Summary: <alloc::boxed::Box>::as_ptr; Argument[0].Reference.Reference; ReturnValue.Reference; value |
|
||||
| 3 | Summary: core::ptr::from_ref; Argument[0]; ReturnValue; value |
|
||||
nodes
|
||||
| deallocation.rs:148:6:148:7 | p1 | semmle.label | p1 |
|
||||
| deallocation.rs:148:30:148:38 | &raw const my_buffer | semmle.label | &raw const my_buffer |
|
||||
@@ -440,4 +454,18 @@ nodes
|
||||
| lifetime.rs:802:6:802:8 | ptr | semmle.label | ptr |
|
||||
| lifetime.rs:802:12:802:24 | get_pointer(...) | semmle.label | get_pointer(...) |
|
||||
| lifetime.rs:808:23:808:25 | ptr | semmle.label | ptr |
|
||||
| main.rs:18:9:18:10 | p1 [&ref] | semmle.label | p1 [&ref] |
|
||||
| main.rs:18:14:18:29 | ...::as_ptr(...) [&ref] | semmle.label | ...::as_ptr(...) [&ref] |
|
||||
| main.rs:18:26:18:28 | &b1 | semmle.label | &b1 |
|
||||
| main.rs:21:19:21:20 | p1 | semmle.label | p1 |
|
||||
| main.rs:29:19:29:20 | p1 | semmle.label | p1 |
|
||||
| main.rs:44:9:44:10 | p2 [&ref] | semmle.label | p2 [&ref] |
|
||||
| main.rs:44:14:44:29 | ...::as_ptr(...) [&ref] | semmle.label | ...::as_ptr(...) [&ref] |
|
||||
| main.rs:44:26:44:28 | &b2 | semmle.label | &b2 |
|
||||
| main.rs:47:9:47:10 | p3 [&ref] | semmle.label | p3 [&ref] |
|
||||
| main.rs:47:14:47:37 | ...::as_mut_ptr(...) [&ref] | semmle.label | ...::as_mut_ptr(...) [&ref] |
|
||||
| main.rs:47:30:47:36 | &mut b3 | semmle.label | &mut b3 |
|
||||
| main.rs:51:23:51:24 | p2 | semmle.label | p2 |
|
||||
| main.rs:52:23:52:24 | p3 | semmle.label | p3 |
|
||||
| main.rs:64:23:64:24 | p2 | semmle.label | p2 |
|
||||
subpaths
|
||||
|
||||
@@ -7,197 +7,201 @@ mod lifetime;
|
||||
use lifetime::*;
|
||||
|
||||
fn use_the_heap() {
|
||||
let _a = Box::new(0x7FFFFFFF);
|
||||
let _b = Box::new(0x7FFFFFFF);
|
||||
let _a = Box::new(0x7FFFFFFF);
|
||||
let _b = Box::new(0x7FFFFFFF);
|
||||
}
|
||||
|
||||
// --- boxes ---
|
||||
|
||||
pub fn test_boxes_into() {
|
||||
let b1: Box<i64> = Box::new(7); // b1 owns the memory for '50'
|
||||
let p1 = Box::as_ptr(&b1); // b1 still owns the memory
|
||||
let b1: Box<i64> = Box::new(7); // b1 owns the memory for '50'
|
||||
let p1 = Box::as_ptr(&b1); // b1 still owns the memory
|
||||
|
||||
unsafe {
|
||||
let v1 = *p1; // GOOD
|
||||
println!(" v1 = {v1}");
|
||||
}
|
||||
unsafe {
|
||||
let v1 = *p1; // GOOD
|
||||
println!(" v1 = {v1}");
|
||||
}
|
||||
|
||||
let v2 = Box::into_inner(b1); // b1 is explicitly freed here, thus p1 is dangling
|
||||
println!(" v2 = {v2}");
|
||||
let v2 = Box::into_inner(b1); // b1 is explicitly freed here, thus p1 is dangling
|
||||
println!(" v2 = {v2}");
|
||||
|
||||
unsafe {
|
||||
let v3 = *p1; // $ MISSING: Alert
|
||||
println!(" v3 = {v3} (!)"); // corrupt in practice
|
||||
}
|
||||
unsafe {
|
||||
let v3 = *p1; // $ MISSING: Alert
|
||||
println!(" v3 = {v3} (!)"); // corrupt in practice
|
||||
}
|
||||
}
|
||||
|
||||
pub fn test_boxes_1(mode: i32) {
|
||||
let p1: *const i64;
|
||||
let p2: *const i64;
|
||||
let p3: *mut i64;
|
||||
let p1: *const i64;
|
||||
let p2: *const i64;
|
||||
let p3: *mut i64;
|
||||
|
||||
{
|
||||
let b1: Box<i64> = Box::new(1);
|
||||
p1 = Box::into_raw(b1); // now owned by p1
|
||||
{
|
||||
let b1: Box<i64> = Box::new(1);
|
||||
p1 = Box::into_raw(b1); // now owned by p1
|
||||
|
||||
let b2: Box<i64> = Box::new(2);
|
||||
p2 = Box::as_ptr(&b2); // still owned by b2
|
||||
let b2: Box<i64> = Box::new(2);
|
||||
p2 = Box::as_ptr(&b2); // $ Source[rust/access-after-lifetime-ended]=b2 -- still owned by b2
|
||||
|
||||
let mut b3: Box<i64> = Box::new(3);
|
||||
p3 = Box::as_mut_ptr(&mut b3); // still owned by b3
|
||||
let mut b3: Box<i64> = Box::new(3);
|
||||
p3 = Box::as_mut_ptr(&mut b3); // still owned by b3
|
||||
|
||||
unsafe {
|
||||
let v1 = *p1; // GOOD
|
||||
let v2 = *p2; // GOOD
|
||||
let v3 = *p3; // GOOD
|
||||
println!(" v1 = {v1}");
|
||||
println!(" v2 = {v2}");
|
||||
println!(" v3 = {v3}");
|
||||
*p3 = 4;
|
||||
}
|
||||
} // (b2, b3 go out of scope, thus p2, p3 are dangling)
|
||||
unsafe {
|
||||
let v1 = *p1; // GOOD
|
||||
let v2 = *p2; // GOOD
|
||||
let v3 = *p3; // GOOD
|
||||
println!(" v1 = {v1}");
|
||||
println!(" v2 = {v2}");
|
||||
println!(" v3 = {v3}");
|
||||
*p3 = 4;
|
||||
}
|
||||
} // (b2, b3 go out of scope, thus p2, p3 are dangling)
|
||||
|
||||
unsafe {
|
||||
if mode == 0 {
|
||||
// reads
|
||||
let v4 = *p1; // GOOD
|
||||
let v5 = *p2; // $ MISSING: Alert
|
||||
let v6 = *p3; // $ MISSING: Alert
|
||||
println!(" v4 = {v4}");
|
||||
println!(" v5 = {v5} (!)"); // corrupt in practice
|
||||
println!(" v6 = {v6} (!)"); // corrupt in practice
|
||||
}
|
||||
if mode == 10 {
|
||||
// write
|
||||
*p3 = 5; // $ MISSING: Alert
|
||||
use_the_heap(); // "malloc: Heap corruption detected"
|
||||
}
|
||||
}
|
||||
unsafe {
|
||||
if mode == 0 {
|
||||
// reads
|
||||
let v4 = *p1; // GOOD
|
||||
let v5 = *p2; // $ Alert[rust/access-after-lifetime-ended]=b2
|
||||
let v6 = *p3; // $ MISSING: Alert
|
||||
println!(" v4 = {v4}");
|
||||
println!(" v5 = {v5} (!)"); // corrupt in practice
|
||||
println!(" v6 = {v6} (!)"); // corrupt in practice
|
||||
}
|
||||
if mode == 10 {
|
||||
// write
|
||||
*p3 = 5; // $ MISSING: Alert
|
||||
use_the_heap(); // "malloc: Heap corruption detected"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn test_boxes_2() {
|
||||
let b1: Box<i64> = Box::new(6); // b1 owns the memory
|
||||
let p1 = Box::into_raw(b1); // now p1 owns the memory
|
||||
let b1: Box<i64> = Box::new(6); // b1 owns the memory
|
||||
let p1 = Box::into_raw(b1); // now p1 owns the memory
|
||||
|
||||
unsafe {
|
||||
let _b2 = Box::from_raw(p1); // now _b2 owns the memory
|
||||
unsafe {
|
||||
let _b2 = Box::from_raw(p1); // now _b2 owns the memory
|
||||
|
||||
let v1 = *p1; // GOOD
|
||||
println!(" v1 = {v1}");
|
||||
} // (_b2 goes out of scope, thus the memory is freed and p1 is dangling)
|
||||
let v1 = *p1; // GOOD
|
||||
println!(" v1 = {v1}");
|
||||
} // (_b2 goes out of scope, thus the memory is freed and p1 is dangling)
|
||||
|
||||
unsafe {
|
||||
let v2 = *p1; // $ MISSING: Alert
|
||||
println!(" v2 = {v2} (!)"); // corrupt in practice
|
||||
}
|
||||
unsafe {
|
||||
let v2 = *p1; // $ MISSING: Alert
|
||||
println!(" v2 = {v2} (!)"); // corrupt in practice
|
||||
}
|
||||
}
|
||||
|
||||
// --- main ---
|
||||
|
||||
fn main() {
|
||||
let mode = std::env::args().nth(1).unwrap_or("0".to_string()).parse::<i32>().unwrap_or(0);
|
||||
// mode = which test cases to explore (0 should be safe; some will crash / segfault).
|
||||
println!("mode = {mode}");
|
||||
let mode = std::env::args()
|
||||
.nth(1)
|
||||
.unwrap_or("0".to_string())
|
||||
.parse::<i32>()
|
||||
.unwrap_or(0);
|
||||
// mode = which test cases to explore (0 should be safe; some will crash / segfault).
|
||||
println!("mode = {mode}");
|
||||
|
||||
println!("test_boxes_into:");
|
||||
test_boxes_into();
|
||||
println!("test_boxes_into:");
|
||||
test_boxes_into();
|
||||
|
||||
println!("test_boxes_1:");
|
||||
test_boxes_1(mode);
|
||||
println!("test_boxes_1:");
|
||||
test_boxes_1(mode);
|
||||
|
||||
println!("test_boxes_2:");
|
||||
test_boxes_2();
|
||||
println!("test_boxes_2:");
|
||||
test_boxes_2();
|
||||
|
||||
// ---
|
||||
// ---
|
||||
|
||||
println!("test_alloc:");
|
||||
test_alloc(mode);
|
||||
println!("test_alloc:");
|
||||
test_alloc(mode);
|
||||
|
||||
println!("test_alloc_array:");
|
||||
test_alloc_array(mode);
|
||||
println!("test_alloc_array:");
|
||||
test_alloc_array(mode);
|
||||
|
||||
println!("test_libc:");
|
||||
test_libc();
|
||||
println!("test_libc:");
|
||||
test_libc();
|
||||
|
||||
println!("test_ptr_invalid:");
|
||||
test_ptr_invalid(mode);
|
||||
println!("test_ptr_invalid:");
|
||||
test_ptr_invalid(mode);
|
||||
|
||||
println!("test_drop:");
|
||||
test_drop();
|
||||
println!("test_drop:");
|
||||
test_drop();
|
||||
|
||||
println!("test_ptr_drop:");
|
||||
test_ptr_drop(mode);
|
||||
println!("test_ptr_drop:");
|
||||
test_ptr_drop(mode);
|
||||
|
||||
println!("test_qhelp_tests:");
|
||||
test_qhelp_examples();
|
||||
println!("test_qhelp_tests:");
|
||||
test_qhelp_examples();
|
||||
|
||||
println!("test_vec_reserve:");
|
||||
test_vec_reserve();
|
||||
println!("test_vec_reserve:");
|
||||
test_vec_reserve();
|
||||
|
||||
// ---
|
||||
// ---
|
||||
|
||||
println!("test_local_dangling:");
|
||||
test_local_dangling();
|
||||
println!("test_local_dangling:");
|
||||
test_local_dangling();
|
||||
|
||||
println!("test_local_in_scope:");
|
||||
test_local_in_scope(mode);
|
||||
println!("test_local_in_scope:");
|
||||
test_local_in_scope(mode);
|
||||
|
||||
println!("test_static:");
|
||||
test_static(mode);
|
||||
println!("test_static:");
|
||||
test_static(mode);
|
||||
|
||||
println!("test_call_contexts:");
|
||||
test_call_contexts();
|
||||
println!("test_call_contexts:");
|
||||
test_call_contexts();
|
||||
|
||||
println!("test_call_contexts_rec:");
|
||||
test_call_contexts_rec();
|
||||
println!("test_call_contexts_rec:");
|
||||
test_call_contexts_rec();
|
||||
|
||||
println!("test_loop:");
|
||||
test_loop();
|
||||
println!("test_loop:");
|
||||
test_loop();
|
||||
|
||||
println!("test_enums:");
|
||||
test_enums();
|
||||
println!("test_enums:");
|
||||
test_enums();
|
||||
|
||||
println!("test_recursive_enums:");
|
||||
test_recursive_enums();
|
||||
println!("test_recursive_enums:");
|
||||
test_recursive_enums();
|
||||
|
||||
println!("test_ptr_to_struct:");
|
||||
test_ptr_to_struct(mode);
|
||||
println!("test_ptr_to_struct:");
|
||||
test_ptr_to_struct(mode);
|
||||
|
||||
println!("test_ptr_from_ref:");
|
||||
test_ptr_from_ref();
|
||||
println!("test_ptr_from_ref:");
|
||||
test_ptr_from_ref();
|
||||
|
||||
println!("test_rc:");
|
||||
test_rc();
|
||||
println!("test_rc:");
|
||||
test_rc();
|
||||
|
||||
println!("test_closures:");
|
||||
test_closures();
|
||||
println!("test_closures:");
|
||||
test_closures();
|
||||
|
||||
println!("test_async:");
|
||||
test_async();
|
||||
println!("test_async:");
|
||||
test_async();
|
||||
|
||||
println!("test_lifetime_annotations:");
|
||||
test_lifetime_annotations();
|
||||
println!("test_lifetime_annotations:");
|
||||
test_lifetime_annotations();
|
||||
|
||||
println!("test_implicit_derefs:");
|
||||
test_implicit_derefs();
|
||||
println!("test_implicit_derefs:");
|
||||
test_implicit_derefs();
|
||||
|
||||
println!("test_members:");
|
||||
test_members();
|
||||
println!("test_members:");
|
||||
test_members();
|
||||
|
||||
println!("test_enum_members:");
|
||||
test_enum_members();
|
||||
println!("test_enum_members:");
|
||||
test_enum_members();
|
||||
|
||||
println!("test_macros:");
|
||||
test_macros();
|
||||
println!("test_macros:");
|
||||
test_macros();
|
||||
|
||||
println!("test_unsafe_function:");
|
||||
unsafe {
|
||||
test_unsafe_function();
|
||||
}
|
||||
println!("test_unsafe_function:");
|
||||
unsafe {
|
||||
test_unsafe_function();
|
||||
}
|
||||
|
||||
println!("test_lifetimes_example_bad:");
|
||||
test_lifetimes_example_bad();
|
||||
println!("test_lifetimes_example_bad:");
|
||||
test_lifetimes_example_bad();
|
||||
|
||||
println!("test_lifetimes_example_good:");
|
||||
test_lifetimes_example_good();
|
||||
println!("test_lifetimes_example_good:");
|
||||
test_lifetimes_example_good();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user