Skip to content

Commit 41a6bf0

Browse files
committed
Rust: Add barrier for null pointer checks to the query.
1 parent d804229 commit 41a6bf0

File tree

4 files changed

+32
-4
lines changed

4 files changed

+32
-4
lines changed

rust/ql/lib/codeql/rust/security/AccessInvalidPointerExtensions.qll

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ private import codeql.rust.dataflow.FlowSource
99
private import codeql.rust.dataflow.FlowSink
1010
private import codeql.rust.Concepts
1111
private import codeql.rust.dataflow.internal.Node
12+
private import codeql.rust.security.Barriers as Barriers
1213

1314
/**
1415
* Provides default sources, sinks and barriers for detecting accesses to
@@ -59,4 +60,10 @@ module AccessInvalidPointer {
5960
private class ModelsAsDataSink extends Sink {
6061
ModelsAsDataSink() { sinkNode(this, "pointer-access") }
6162
}
63+
64+
/**
65+
* A barrier for invalid pointer access vulnerabilities for values found to be `null` in
66+
* a comparison.
67+
*/
68+
private class NullCheckBarrier extends Barrier instanceof Barriers::NotNullCheckBarrier { }
6269
}

rust/ql/lib/codeql/rust/security/Barriers.qll

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ private import codeql.rust.dataflow.DataFlow
88
private import codeql.rust.internal.TypeInference as TypeInference
99
private import codeql.rust.internal.Type
1010
private import codeql.rust.frameworks.stdlib.Builtins
11+
private import codeql.rust.controlflow.ControlFlowGraph as Cfg
12+
private import codeql.rust.controlflow.CfgNodes as CfgNodes
1113

1214
/**
1315
* A node whose type is a numeric or boolean type, which may be an appropriate
@@ -40,3 +42,25 @@ class IntegralOrBooleanTypeBarrier extends DataFlow::Node {
4042
)
4143
}
4244
}
45+
46+
/**
47+
* Holds if guard expression `g` having result `branch` indicates that the
48+
* sub-expression `node` is not null. For example when `ptr.is_null()` is
49+
* `false`, we have that `ptr` is not null.
50+
*/
51+
private predicate notNullCheck(CfgNodes::AstCfgNode g, Cfg::CfgNode node, boolean branch) {
52+
exists(MethodCallExpr call |
53+
call.getStaticTarget().getName().getText() = "is_null" and
54+
g = call.getACfgNode() and
55+
node = call.getReceiver().getACfgNode() and
56+
branch = false
57+
)
58+
}
59+
60+
/**
61+
* A node representing a check that the value is not null, which may be an
62+
* appropriate taint flow barrier for some queries.
63+
*/
64+
class NotNullCheckBarrier extends DataFlow::Node {
65+
NotNullCheckBarrier() { this = DataFlow::BarrierGuard<notNullCheck/3>::getABarrierNode() }
66+
}

rust/ql/test/query-tests/security/CWE-825/AccessInvalidPointer.expected

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
| deallocation.rs:210:7:210:9 | ptr | deallocation.rs:199:9:199:26 | ...::null_mut | deallocation.rs:210:7:210:9 | ptr | This operation dereferences a pointer that may be $@. | deallocation.rs:199:9:199:26 | ...::null_mut | invalid |
2727
| deallocation.rs:210:7:210:9 | ptr | deallocation.rs:207:9:207:26 | ...::null_mut | deallocation.rs:210:7:210:9 | ptr | This operation dereferences a pointer that may be $@. | deallocation.rs:207:9:207:26 | ...::null_mut | invalid |
2828
| deallocation.rs:226:13:226:21 | const_ptr | deallocation.rs:219:15:219:32 | ...::null_mut | deallocation.rs:226:13:226:21 | const_ptr | This operation dereferences a pointer that may be $@. | deallocation.rs:219:15:219:32 | ...::null_mut | invalid |
29-
| deallocation.rs:229:13:229:21 | const_ptr | deallocation.rs:219:15:219:32 | ...::null_mut | deallocation.rs:229:13:229:21 | const_ptr | This operation dereferences a pointer that may be $@. | deallocation.rs:219:15:219:32 | ...::null_mut | invalid |
3029
| deallocation.rs:274:15:274:16 | p1 | deallocation.rs:270:3:270:25 | ...::drop_in_place | deallocation.rs:274:15:274:16 | p1 | This operation dereferences a pointer that may be $@. | deallocation.rs:270:3:270:25 | ...::drop_in_place | invalid |
3130
| deallocation.rs:274:15:274:16 | p1 | deallocation.rs:270:3:270:25 | ...::drop_in_place | deallocation.rs:274:15:274:16 | p1 | This operation dereferences a pointer that may be $@. | deallocation.rs:270:3:270:25 | ...::drop_in_place | invalid |
3231
| deallocation.rs:342:18:342:20 | ptr | deallocation.rs:336:3:336:25 | ...::drop_in_place | deallocation.rs:342:18:342:20 | ptr | This operation dereferences a pointer that may be $@. | deallocation.rs:336:3:336:25 | ...::drop_in_place | invalid |
@@ -81,7 +80,6 @@ edges
8180
| deallocation.rs:207:9:207:26 | ...::null_mut | deallocation.rs:207:9:207:28 | ...::null_mut(...) | provenance | Src:MaD:8 MaD:8 |
8281
| deallocation.rs:207:9:207:28 | ...::null_mut(...) | deallocation.rs:207:3:207:5 | ptr | provenance | |
8382
| deallocation.rs:219:3:219:11 | const_ptr | deallocation.rs:226:13:226:21 | const_ptr | provenance | |
84-
| deallocation.rs:219:3:219:11 | const_ptr | deallocation.rs:229:13:229:21 | const_ptr | provenance | |
8583
| deallocation.rs:219:15:219:32 | ...::null_mut | deallocation.rs:219:15:219:34 | ...::null_mut(...) | provenance | Src:MaD:8 MaD:8 |
8684
| deallocation.rs:219:15:219:34 | ...::null_mut(...) | deallocation.rs:219:3:219:11 | const_ptr | provenance | |
8785
| deallocation.rs:270:3:270:25 | ...::drop_in_place | deallocation.rs:270:27:270:28 | [post] p1 | provenance | Src:MaD:6 MaD:6 |
@@ -161,7 +159,6 @@ nodes
161159
| deallocation.rs:219:15:219:32 | ...::null_mut | semmle.label | ...::null_mut |
162160
| deallocation.rs:219:15:219:34 | ...::null_mut(...) | semmle.label | ...::null_mut(...) |
163161
| deallocation.rs:226:13:226:21 | const_ptr | semmle.label | const_ptr |
164-
| deallocation.rs:229:13:229:21 | const_ptr | semmle.label | const_ptr |
165162
| deallocation.rs:270:3:270:25 | ...::drop_in_place | semmle.label | ...::drop_in_place |
166163
| deallocation.rs:270:3:270:25 | ...::drop_in_place | semmle.label | ...::drop_in_place |
167164
| deallocation.rs:270:27:270:28 | [post] p1 | semmle.label | [post] p1 |

rust/ql/test/query-tests/security/CWE-825/deallocation.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ pub unsafe fn test_ptr_invalid_conditions(mode: i32) {
226226
let v = (*const_ptr).value; // $ Alert[rust/access-invalid-pointer]
227227
println!(" cond10 v = {v}");
228228
} else {
229-
let v = (*const_ptr).value; // $ SPURIOUS: Alert[rust/access-invalid-pointer] good - unreachable with null pointer
229+
let v = (*const_ptr).value; // $ good - unreachable with null pointer
230230
println!(" cond11 v = {v}");
231231
}
232232
}

0 commit comments

Comments
 (0)