Skip to content

Destructor of packed structs can move dangling references. #143411

Open
@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-prioritizeIssue: Indicates that prioritization has been requested for this issue.I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessT-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