rust-lang / rust-lang/rust

Destructor of packed structs can move dangling references.

Open
#143,411 6 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-destructors A-repr-packed C-bug I-unsound P-high T-compiler T-opsem
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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.