Skip to content
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

libtest UB with custom allocator, per miri #138839

Closed
alecmocatta opened this issue Mar 22, 2025 · 3 comments
Closed

libtest UB with custom allocator, per miri #138839

alecmocatta opened this issue Mar 22, 2025 · 3 comments
Labels
C-discussion Category: Discussion or questions that doesn't represent real issues. T-opsem Relevant to the opsem team

Comments

@alecmocatta
Copy link
Contributor

I tried this code:

git clone https://github.com/alecmocatta/memcheck
cargo miri test

I expected to see this happen: test passes.

Instead, this happened:

error: Undefined Behavior: trying to retag from <98686> for Unique permission at alloc46622[0x38], but that tag does not exist in the borrow stack for this location
   --> /Users/alecmocatta/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/ptr/mut_ptr.rs:683:18
    |
683 |         unsafe { &mut *self }
    |                  ^^^^^^^^^^
    |                  |
    |                  trying to retag from <98686> for Unique permission at alloc46622[0x38], but that tag does not exist in the borrow stack for this location
    |                  this error occurs as part of retag at alloc46622[0x38..0x42]
    |
    = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
    = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
    = help: <98686> was created by a Unique retag at offsets [0x0..0x38]
    = note: BACKTRACE (of the first span):
    = note: inside `std::ptr::mut_ptr::<impl *mut memcheck::Check>::as_mut_unchecked::<'_>` at /Users/alecmocatta/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/ptr/mut_ptr.rs:683:18: 683:28
note: inside `<memcheck::Memcheck<std::alloc::System> as std::alloc::GlobalAlloc>::dealloc`
   --> /Users/alecmocatta/Downloads/memcheck/src/lib.rs:42:15
    |
42  |         let check = ptr.add(l.size()).cast::<Check>().as_mut_unchecked();
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: inside `_::__rust_dealloc`
   --> tests/test.rs:9:19
    |
8   | #[global_allocator]
    | ------------------- in this procedural macro expansion
9   | static ALLOCATOR: Memcheck<alloc::System> = Memcheck::new(alloc::System);
    |                   ^^^^^^^^^^^^^^^^^^^^^^^
    = note: inside `alloc::raw_vec::RawVecInner::deallocate` at /Users/alecmocatta/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/alloc/src/raw_vec/mod.rs:757:17: 757:51
    = note: inside `<alloc::raw_vec::RawVec<getopts::Opt> as std::ops::Drop>::drop` at /Users/alecmocatta/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/alloc/src/raw_vec/mod.rs:406:18: 406:50
    = note: inside `std::ptr::drop_in_place::<alloc::raw_vec::RawVec<getopts::Opt>> - shim(Some(alloc::raw_vec::RawVec<getopts::Opt>))` at /Users/alecmocatta/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:523:1: 523:56
    = note: inside `std::ptr::drop_in_place::<std::vec::Vec<getopts::Opt>> - shim(Some(std::vec::Vec<getopts::Opt>))` at /Users/alecmocatta/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:523:1: 523:56
    = note: inside `std::ptr::drop_in_place::<getopts::Opt> - shim(Some(getopts::Opt))` at /Users/alecmocatta/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:523:1: 523:56
    = note: inside `std::ptr::drop_in_place::<[getopts::Opt]> - shim(Some([getopts::Opt]))` at /Users/alecmocatta/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:523:1: 523:56
    = note: inside `<std::vec::Vec<getopts::Opt> as std::ops::Drop>::drop` at /Users/alecmocatta/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/alloc/src/vec/mod.rs:3798:13: 3798:91
    = note: inside `std::ptr::drop_in_place::<std::vec::Vec<getopts::Opt>> - shim(Some(std::vec::Vec<getopts::Opt>))` at /Users/alecmocatta/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:523:1: 523:56
    = note: inside `std::ptr::drop_in_place::<getopts::Matches> - shim(Some(getopts::Matches))` at /Users/alecmocatta/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:523:1: 523:56
    = note: inside `test::cli::parse_opts_impl` at /Users/alecmocatta/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/test/src/cli.rs:311:1: 311:2
    = note: inside `test::test::parse_opts` at /Users/alecmocatta/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/test/src/cli.rs:218:23: 218:47
    = note: inside `test::test_main` at /Users/alecmocatta/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/test/src/lib.rs:101:26: 101:47
    = note: inside `test::test_main_static` at /Users/alecmocatta/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/test/src/lib.rs:173:5: 173:40
    = note: inside `main`

There could be a bug in my GlobalAlloc impl, though miri raises no UB when using it outside of libtest.

This crate was written to debug occasionally seeing this assertion #124671 still being hit in production.

Meta

rustc 1.87.0-nightly (be73c1f46 2025-03-21)
binary: rustc
commit-hash: be73c1f4617c97bce81b2694a767353300a75072
commit-date: 2025-03-21
host: aarch64-apple-darwin
release: 1.87.0-nightly
LLVM version: 20.1.1
@alecmocatta alecmocatta added the C-bug Category: This is a bug. label Mar 22, 2025
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Mar 22, 2025
@jieyouxu jieyouxu added A-allocators Area: Custom and system allocators I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Mar 22, 2025
@rustbot rustbot added the I-prioritize Issue: Indicates that prioritization has been requested for this issue. label Mar 22, 2025
@saethlin
Copy link
Member

saethlin commented Mar 22, 2025

That diagnostic should also have a note that explains where the tag was created. Does it?

Oh I see it now. There just isn't a span.

@saethlin
Copy link
Member

saethlin commented Mar 22, 2025

The problem is in your code. This strategy you are trying to implement is a variation of the &Header pattern (rust-lang/unsafe-code-guidelines#256), which is incompatible with Stacked Borrows:
https://github.com/alecmocatta/memcheck/blob/dfaf06fe401316cfb06c308238eb1c3b20a23acb/src/lib.rs#L42

@saethlin saethlin closed this as not planned Won't fix, can't repro, duplicate, stale Mar 22, 2025
@saethlin saethlin added C-discussion Category: Discussion or questions that doesn't represent real issues. T-opsem Relevant to the opsem team and removed A-allocators Area: Custom and system allocators I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness C-bug Category: This is a bug. I-prioritize Issue: Indicates that prioritization has been requested for this issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Mar 22, 2025
@tgross35
Copy link
Contributor

For completeness, you should try with -Zmiri-tree-borrows

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-discussion Category: Discussion or questions that doesn't represent real issues. T-opsem Relevant to the opsem team
Projects
None yet
Development

No branches or pull requests

5 participants