-
Notifications
You must be signed in to change notification settings - Fork 3
Fix: Aliasing UB Reported by Miri #3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
… problem
Before this fix:
$ MIRIFLAGS=-Zmiri-tree-borrows cargo miri test
test linked_list::tests::test_push_back ... error: Undefined Behavior: deallocation through <137613> at alloc42011[0x0] is forbidden
--> /home/gh-zjp-CN/.rustup/toolchains/nightly-aarch64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/boxed.rs:1686:17
|
1686 | self.1.deallocate(From::from(ptr.cast()), layout);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here
|
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
= help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/tree-borrows.md for further information
= help: the accessed tag <137613> is a child of the conflicting tag <133189>
= help: the conflicting tag <133189> has state Frozen which forbids this deallocation (acting as a child write access)
help: the accessed tag <137613> was created here
--> src/linked_list.rs:233:15
|
233 | while self.pop_front().is_some() {}
| ^^^^^^^^^^^^^^^^
help: the conflicting tag <133189> was created here, in the initial state Cell
--> src/raw_list.rs:162:28
|
162 | let new_ptr = Some(NonNull::from(new));
| ^^^^^^^^^^^^^^^^^^
= note: BACKTRACE (of the first span) on thread `linked_list::te`:
= note: inside `<std::boxed::Box<linked_list::tests::Example> as std::ops::Drop>::drop` at /home/gh-zjp-CN/.rustup/toolchains/nightly-aarch64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/boxed.rs:1686:17: 1686:66
= note: inside `std::ptr::drop_in_place::<std::boxed::Box<linked_list::tests::Example>> - shim(Some(std::boxed::Box<linked_list::tests::Example>))` at /home/gh-zjp-CN/.rustup/toolchains/nightly-aarch64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:805:1: 807:25
= note: inside `std::ptr::drop_in_place::<std::option::Option<std::boxed::Box<linked_list::tests::Example>>> - shim(Some(std::option::Option<std::boxed::Box<linked_list::tests::Example>>))` at /home/gh-zjp-CN/.rustup/toolchains/nightly-aarch64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:805:1: 807:25
note: inside `<linked_list::List<std::boxed::Box<linked_list::tests::Example>> as std::ops::Drop>::drop`
--> src/linked_list.rs:233:40
|
233 | while self.pop_front().is_some() {}
| ^
= note: inside `std::ptr::drop_in_place::<linked_list::List<std::boxed::Box<linked_list::tests::Example>>> - shim(Some(linked_list::List<std::boxed::Box<linked_list::tests::Example>>))` at /home/gh-zjp-CN/.rustup/toolchains/nightly-aarch64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:805:1: 807:25
note: inside closure
--> src/linked_list.rs:342:24
|
341 | #[test]
| ------- in this attribute macro expansion
342 | fn test_push_back() {
| ^
============================================================
After the fix:
$ MIRIFLAGS=-Zmiri-tree-borrows cargo miri test
running 5 tests
test linked_list::tests::test_push_back ... ok
test raw_list::tests::test_one_insert_after ... ok
test raw_list::tests::test_one_removal ... ok
test raw_list::tests::test_push_back ... ok
test raw_list::tests::test_push_front ... ok
test result: ok. 5 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 3.78s
Doc-tests linked_list_r4l
running 3 tests
test src/lib.rs - def_node (line 113) ... ignored
test src/lib.rs - (line 16) ... ok
test src/lib.rs - def_node (line 124) ... ok
test result: ok. 2 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 0.19s
============================================================
Note the fix still has some tests incur aliasing violation from stack borrows view
$ cargo miri test
running 5 tests
test linked_list::tests::test_push_back ... ok
test raw_list::tests::test_one_insert_after ... error: Undefined Behavior: trying to retag from <165717> for SharedReadWrite permission at all
oc50876[0x0], but that tag does not exist in the borrow stack for this location
--> src/raw_list.rs:358:23
|
358 | Some(unsafe { &*cur.as_ptr() })
| ^^^^^^^^^^^^^^ this error occurs as part of retag at alloc50876[0x0..0x18]
|
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are st
ill experimental
= help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
help: <165717> was created by a SharedReadWrite retag at offsets [0x0..0x11]
--> src/raw_list.rs:149:58
|
149 | self.insert_after_priv(existing, new_entry, Some(NonNull::from(new)));
| ^^^^^^^^^^^^^^^^^^
help: <165717> was later invalidated at offsets [0x0..0x18] by a Unique retag
--> src/raw_list.rs:594:29
|
594 | v.insert(i + 1, extra);
| ^^^^^
= note: BACKTRACE (of the first span) on thread `raw_list::tests`:
= note: inside `raw_list::Cursor::<'_, raw_list::tests::Example>::current` at src/raw_list.rs:358:23: 358:37
note: inside `<raw_list::Iterator<'_, raw_list::tests::Example> as std::iter::Iterator>::next`
--> src/raw_list.rs:453:19
|
453 | let ret = self.cursor_front.current()?;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: inside `<std::iter::Enumerate<raw_list::Iterator<'_, raw_list::tests::Example>> as std::iter::Iterator>::next` at /home/gh-zjp-CN/
.rustup/toolchains/nightly-aarch64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/adapters/enumerate.rs:80:17: 80:33
note: inside `raw_list::tests::test_one_insert_after`
--> src/raw_list.rs:588:9
|
588 | / test_each_element(1, 10, |v, list, i, extra| {
... |
594 | | v.insert(i + 1, extra);
595 | | });
| |__________^
note: inside closure
--> src/raw_list.rs:587:31
|
586 | #[test]
| ------- in this attribute macro expansion
587 | fn test_one_insert_after() {
| ^
equation314
approved these changes
Nov 16, 2025
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR fixes violations of the aliasing rules
ptr.as_ref()and thus all pointers are based it, which is fine as long as no mutation happens. But the mutation does happen in the drop code of Wrapper (i.e. the Box or Arc in the crate). The diagnostic of tree borrows shows it clearer as followsMIRIFLAGS=-Zmiri-tree-borrows cargo miri test
tests::fifo::bench_removeandtests::fifo::test_schedwithout further efforts.I set up a step of miri check in CI as well.