Destructor of packed structs can move dangling references.
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
The below code causes Miri to report UB
#![allow(dead_code)]
#[repr(C, packed)]
struct Foo<'a> {
val: Bar<'a>,
}
struct Bar<'a>(&'a mut i32, Box<()>);
fn main() {
let _v;
{
let mut b = Box::new(1);
_v = Foo {
val: Bar(&mut b, Box::new(())),
};
}
}
Miri output:
Running `/playground/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/bin/cargo-miri runner target/miri/x86_64-unknown-linux-gnu/debug/playground`
error: Undefined Behavior: constructing invalid value at .0: encountered a dangling reference (use-after-free)
--> /playground/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:799:1
|
799 | pub unsafe fn drop_in_place<T: PointeeSized>(to_drop: *mut T) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
= note: BACKTRACE:
= note: inside `std::ptr::drop_in_place::<Foo<'_>> - shim(Some(Foo<'_>))` at /playground/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:799:1: 799:62
note: inside `main`
--> src/main.rs:18:1
|
18 | }
| ^
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
error: aborting due to 1 previous error
This occurs because, as documented in the docs for drop_in_place, the destructor of Foo will move the field val to a new place, in order for the value to be aligned before calling the destructor of Bar. This causes a move of a dangling reference as the destructor of the _v value is ran, which is undefined behavior.
Meta
Reproducible on the playground with 1.90.0-nightly (2025-07-03 da58c051315268a197ce)
@rustbot labels +I-unsound +A-destructors +A-repr-packed
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the example with Miri and inspect the drop_in_place documentation and implementation at library/core/src/ptr/mod.rs, along with the src/main.rs example. Trace how destruction of the repr(C, packed) Foo handles val and confirm the dangling-reference move. Done means the reported undefined behavior is addressed and covered by a regression test.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100