Skip to content

Destructor of packed structs can move dangling references. #143411

@theemathas

Description

@theemathas

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-destructorsArea: Destructors (`Drop`, …)A-repr-packedArea: the naughtiest reprC-bugCategory: This is a bug.I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessP-highHigh priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-opsemRelevant to the opsem team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions