Skip to content

Commit bcfcce3

Browse files
hvitvedCopilot
andcommitted
Rust: Update query expectations after removing parentheses
Record newly detected accesses through dangling field pointers and regenerate the affected query expectations. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
1 parent 50cf60b commit bcfcce3

4 files changed

Lines changed: 32 additions & 8 deletions

File tree

‎rust/ql/lib/change-notes/2026-11-03-parenthesized-expressions-and-patterns.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
category: minorAnalysis
33
---
44
* The Rust AST no longer exposes `ParenExpr` and `ParenPat` nodes. Parenthesized expressions and patterns are represented by their inner entities instead.
5+
* The `rust/access-after-lifetime-ended` query now detects more accesses through pointers to struct fields created by `std::ptr::addr_of!` and `std::ptr::addr_of_mut!`.

‎rust/ql/test/query-tests/security/CWE-798/HardcodedCryptographicValue.expected‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
| test_cipher.rs:131:27:131:35 | [0xff; 12] | test_cipher.rs:131:27:131:35 | [0xff; 12] | test_cipher.rs:133:29:133:42 | &... | This hard-coded value is used as $@. | test_cipher.rs:133:29:133:42 | &... | a nonce |
1717
| test_cookie.rs:17:28:17:34 | [0; 64] | test_cookie.rs:17:28:17:34 | [0; 64] | test_cookie.rs:18:26:18:32 | &array1 | This hard-coded value is used as $@. | test_cookie.rs:18:26:18:32 | &array1 | a key |
1818
| test_cookie.rs:21:28:21:34 | [0; 64] | test_cookie.rs:21:28:21:34 | [0; 64] | test_cookie.rs:22:26:22:32 | &array2 | This hard-coded value is used as $@. | test_cookie.rs:22:26:22:32 | &array2 | a key |
19-
| test_cookie.rs:25:16:29:5 | match ... { ... } | test_cookie.rs:25:16:29:5 | match ... { ... } | test_cookie.rs:30:26:30:40 | str3.as_bytes() | This hard-coded value is used as $@. | test_cookie.rs:30:26:30:40 | str3.as_bytes() | a key |
19+
| test_cookie.rs:25:16:29:5 | match val { ... } | test_cookie.rs:25:16:29:5 | match val { ... } | test_cookie.rs:30:26:30:40 | str3.as_bytes() | This hard-coded value is used as $@. | test_cookie.rs:30:26:30:40 | str3.as_bytes() | a key |
2020
| test_cookie.rs:33:27:37:5 | [...] | test_cookie.rs:33:27:37:5 | [...] | test_cookie.rs:38:26:38:32 | &array4 | This hard-coded value is used as $@. | test_cookie.rs:38:26:38:32 | &array4 | a key |
2121
| test_cookie.rs:54:28:54:36 | [0u8; 64] | test_cookie.rs:54:28:54:36 | [0u8; 64] | test_cookie.rs:58:34:58:39 | array2 | This hard-coded value is used as $@. | test_cookie.rs:58:34:58:39 | array2 | a key |
2222
| test_cookie.rs:65:23:65:25 | 0u8 | test_cookie.rs:65:23:65:25 | 0u8 | test_cookie.rs:69:34:69:39 | array3 | This hard-coded value is used as $@. | test_cookie.rs:69:34:69:39 | array3 | a key |
@@ -122,7 +122,7 @@ edges
122122
| test_cookie.rs:22:26:22:32 | &array2 [&ref] | test_cookie.rs:22:26:22:32 | &array2 | provenance | Sink:MaD:6 |
123123
| test_cookie.rs:22:27:22:32 | array2 | test_cookie.rs:22:26:22:32 | &array2 [&ref] | provenance | |
124124
| test_cookie.rs:25:9:25:12 | str3 | test_cookie.rs:30:26:30:29 | str3 | provenance | |
125-
| test_cookie.rs:25:16:29:5 | match ... { ... } | test_cookie.rs:25:9:25:12 | str3 | provenance | |
125+
| test_cookie.rs:25:16:29:5 | match val { ... } | test_cookie.rs:25:9:25:12 | str3 | provenance | |
126126
| test_cookie.rs:30:26:30:29 | str3 | test_cookie.rs:30:26:30:40 | str3.as_bytes() [&ref] | provenance | MaD:19 |
127127
| test_cookie.rs:30:26:30:40 | str3.as_bytes() [&ref] | test_cookie.rs:30:26:30:40 | str3.as_bytes() | provenance | Sink:MaD:6 |
128128
| test_cookie.rs:33:9:33:14 | array4 | test_cookie.rs:38:27:38:32 | array4 | provenance | |
@@ -275,7 +275,7 @@ nodes
275275
| test_cookie.rs:22:26:22:32 | &array2 [&ref] | semmle.label | &array2 [&ref] |
276276
| test_cookie.rs:22:27:22:32 | array2 | semmle.label | array2 |
277277
| test_cookie.rs:25:9:25:12 | str3 | semmle.label | str3 |
278-
| test_cookie.rs:25:16:29:5 | match ... { ... } | semmle.label | match ... { ... } |
278+
| test_cookie.rs:25:16:29:5 | match val { ... } | semmle.label | match val { ... } |
279279
| test_cookie.rs:30:26:30:29 | str3 | semmle.label | str3 |
280280
| test_cookie.rs:30:26:30:40 | str3.as_bytes() | semmle.label | str3.as_bytes() |
281281
| test_cookie.rs:30:26:30:40 | str3.as_bytes() [&ref] | semmle.label | str3.as_bytes() [&ref] |

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@
1616
| lifetime.rs:317:13:317:18 | result | lifetime.rs:289:25:289:26 | &x | lifetime.rs:317:13:317:18 | result | Access of a pointer to $@ after its lifetime has ended. | lifetime.rs:289:17:289:17 | x | x |
1717
| lifetime.rs:411:16:411:17 | p1 | lifetime.rs:383:31:383:37 | &raw mut my_pair | lifetime.rs:411:16:411:17 | p1 | Access of a pointer to $@ after its lifetime has ended. | lifetime.rs:382:11:382:17 | my_pair | my_pair |
1818
| lifetime.rs:416:16:416:17 | p1 | lifetime.rs:383:31:383:37 | &raw mut my_pair | lifetime.rs:416:16:416:17 | p1 | Access of a pointer to $@ after its lifetime has ended. | lifetime.rs:382:11:382:17 | my_pair | my_pair |
19+
| lifetime.rs:421:15:421:16 | p2 | lifetime.rs:384:27:384:35 | &raw const ... | lifetime.rs:421:15:421:16 | p2 | Access of a pointer to $@ after its lifetime has ended. | lifetime.rs:382:11:382:17 | my_pair | my_pair |
20+
| lifetime.rs:422:15:422:16 | p3 | lifetime.rs:385:31:385:39 | &raw mut ... | lifetime.rs:422:15:422:16 | p3 | Access of a pointer to $@ after its lifetime has ended. | lifetime.rs:382:11:382:17 | my_pair | my_pair |
1921
| lifetime.rs:428:7:428:8 | p1 | lifetime.rs:383:31:383:37 | &raw mut my_pair | lifetime.rs:428:7:428:8 | p1 | Access of a pointer to $@ after its lifetime has ended. | lifetime.rs:382:11:382:17 | my_pair | my_pair |
22+
| lifetime.rs:429:6:429:7 | p3 | lifetime.rs:385:31:385:39 | &raw mut ... | lifetime.rs:429:6:429:7 | p3 | Access of a pointer to $@ after its lifetime has ended. | lifetime.rs:382:11:382:17 | my_pair | my_pair |
2023
| lifetime.rs:433:7:433:8 | p1 | lifetime.rs:383:31:383:37 | &raw mut my_pair | lifetime.rs:433:7:433:8 | p1 | Access of a pointer to $@ after its lifetime has ended. | lifetime.rs:382:11:382:17 | my_pair | my_pair |
2124
| lifetime.rs:459:13:459:14 | p1 | lifetime.rs:442:17:442:23 | &my_val | lifetime.rs:459:13:459:14 | p1 | Access of a pointer to $@ after its lifetime has ended. | lifetime.rs:441:6:441:11 | my_val | my_val |
2225
| lifetime.rs:460:13:460:31 | get_ptr_from_ref(...) | lifetime.rs:442:17:442:23 | &my_val | lifetime.rs:460:13:460:31 | get_ptr_from_ref(...) | Access of a pointer to $@ after its lifetime has ended. | lifetime.rs:441:6:441:11 | my_val | my_val |
@@ -117,6 +120,15 @@ edges
117120
| lifetime.rs:383:3:383:4 | p1 | lifetime.rs:428:7:428:8 | p1 | provenance | |
118121
| lifetime.rs:383:3:383:4 | p1 | lifetime.rs:433:7:433:8 | p1 | provenance | |
119122
| lifetime.rs:383:31:383:37 | &raw mut my_pair | lifetime.rs:383:3:383:4 | p1 | provenance | |
123+
| lifetime.rs:384:3:384:4 | p2 | lifetime.rs:394:14:394:15 | p2 | provenance | |
124+
| lifetime.rs:384:3:384:4 | p2 | lifetime.rs:421:15:421:16 | p2 | provenance | |
125+
| lifetime.rs:384:27:384:35 | &raw const ... | lifetime.rs:384:3:384:4 | p2 | provenance | |
126+
| lifetime.rs:385:3:385:4 | p3 | lifetime.rs:395:14:395:15 | p3 | provenance | |
127+
| lifetime.rs:385:3:385:4 | p3 | lifetime.rs:400:5:400:6 | p3 | provenance | |
128+
| lifetime.rs:385:3:385:4 | p3 | lifetime.rs:400:5:400:6 | p3 | provenance | |
129+
| lifetime.rs:385:31:385:39 | &raw mut ... | lifetime.rs:385:3:385:4 | p3 | provenance | |
130+
| lifetime.rs:400:5:400:6 | p3 | lifetime.rs:422:15:422:16 | p3 | provenance | |
131+
| lifetime.rs:400:5:400:6 | p3 | lifetime.rs:429:6:429:7 | p3 | provenance | |
120132
| lifetime.rs:442:6:442:7 | r1 | lifetime.rs:443:42:443:43 | r1 | provenance | |
121133
| lifetime.rs:442:17:442:23 | &my_val | lifetime.rs:442:6:442:7 | r1 | provenance | |
122134
| lifetime.rs:443:6:443:7 | p1 | lifetime.rs:446:13:446:14 | p1 | provenance | |
@@ -262,13 +274,24 @@ nodes
262274
| lifetime.rs:355:28:355:30 | ptr | semmle.label | ptr |
263275
| lifetime.rs:383:3:383:4 | p1 | semmle.label | p1 |
264276
| lifetime.rs:383:31:383:37 | &raw mut my_pair | semmle.label | &raw mut my_pair |
277+
| lifetime.rs:384:3:384:4 | p2 | semmle.label | p2 |
278+
| lifetime.rs:384:27:384:35 | &raw const ... | semmle.label | &raw const ... |
279+
| lifetime.rs:385:3:385:4 | p3 | semmle.label | p3 |
280+
| lifetime.rs:385:31:385:39 | &raw mut ... | semmle.label | &raw mut ... |
265281
| lifetime.rs:388:15:388:16 | p1 | semmle.label | p1 |
266282
| lifetime.rs:391:15:391:16 | p1 | semmle.label | p1 |
283+
| lifetime.rs:394:14:394:15 | p2 | semmle.label | p2 |
284+
| lifetime.rs:395:14:395:15 | p3 | semmle.label | p3 |
267285
| lifetime.rs:399:6:399:7 | p1 | semmle.label | p1 |
286+
| lifetime.rs:400:5:400:6 | p3 | semmle.label | p3 |
287+
| lifetime.rs:400:5:400:6 | p3 | semmle.label | p3 |
268288
| lifetime.rs:401:6:401:7 | p1 | semmle.label | p1 |
269289
| lifetime.rs:411:16:411:17 | p1 | semmle.label | p1 |
270290
| lifetime.rs:416:16:416:17 | p1 | semmle.label | p1 |
291+
| lifetime.rs:421:15:421:16 | p2 | semmle.label | p2 |
292+
| lifetime.rs:422:15:422:16 | p3 | semmle.label | p3 |
271293
| lifetime.rs:428:7:428:8 | p1 | semmle.label | p1 |
294+
| lifetime.rs:429:6:429:7 | p3 | semmle.label | p3 |
272295
| lifetime.rs:433:7:433:8 | p1 | semmle.label | p1 |
273296
| lifetime.rs:442:6:442:7 | r1 | semmle.label | r1 |
274297
| lifetime.rs:442:17:442:23 | &my_val | semmle.label | &my_val |

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -381,8 +381,8 @@ pub fn test_ptr_to_struct(mode: i32) {
381381
{
382382
let mut my_pair = MyPair { a: 1, b: 2};
383383
p1 = std::ptr::addr_of_mut!(my_pair); // $ Source[rust/access-after-lifetime-ended]=my_pair
384-
p2 = std::ptr::addr_of!(my_pair.a); // $ MISSING: Source[rust/access-after-lifetime-ended]=my_pair_a
385-
p3 = std::ptr::addr_of_mut!(my_pair.b); // $ MISSING: Source[rust/access-after-lifetime-ended]=my_pair_b
384+
p2 = std::ptr::addr_of!(my_pair.a); // $ Source[rust/access-after-lifetime-ended]=my_pair_a
385+
p3 = std::ptr::addr_of_mut!(my_pair.b); // $ Source[rust/access-after-lifetime-ended]=my_pair_b
386386

387387
unsafe {
388388
let v1 = (*p1).a; // GOOD
@@ -418,15 +418,15 @@ pub fn test_ptr_to_struct(mode: i32) {
418418
},
419419
221 => {
420420
// more reads
421-
let v7 = *p2; // $ MISSING: Alert
422-
let v8 = *p3; // $ MISSING: Alert
421+
let v7 = *p2; // $ Alert[rust/access-after-lifetime-ended]=my_pair_a
422+
let v8 = *p3; // $ Alert[rust/access-after-lifetime-ended]=my_pair_b
423423
println!(" v7 = {v7} (!)"); // dropped in practice
424424
println!(" v8 = {v8} (!)"); // dropped in practice
425425
},
426426
222 => {
427427
// writes
428428
(*p1).a = 6; // $ Alert[rust/access-after-lifetime-ended]=my_pair
429-
*p3 = 7; // $ MISSING: Alert
429+
*p3 = 7; // $ Alert[rust/access-after-lifetime-ended]=my_pair_b
430430
},
431431
223 => {
432432
// another write

0 commit comments

Comments
 (0)