Skip to content

core::iter::repeat_n is unsound with Box<T> #130141

Description

@jwong101

This is technically different from #130140 as there's no UAF. However, using core::iter::repeat_n with Box<T> has undefined behavior if you use the last/original element after moving the iterator, since the Box field has noalias properties.

fn main() {
    let mut y = std::iter::repeat_n(Box::new(0), 1);
    let x = y.next().unwrap();
    let _z = y;
    dbg!(*x);
}
Miri Backtrace

Compiling playground v0.0.1 (/playground)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.96s
     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: attempting a read access using <2719> at alloc1241[0x0], but that tag does not exist in the borrow stack for this location
 --> src/main.rs:5:5
  |
5 |     dbg!(*x);
  |     ^^^^^^^^
  |     |
  |     attempting a read access using <2719> at alloc1241[0x0], but that tag does not exist in the borrow stack for this location
  |     this error occurs as part of an access at alloc1241[0x0..0x4]
  |
  = 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: <2719> was created by a Unique retag at offsets [0x0..0x4]
 --> src/main.rs:3:13
  |
3 |     let x = y.next().unwrap();
  |             ^^^^^^^^^^^^^^^^^
help: <2719> was later invalidated at offsets [0x0..0x4] by a Unique retag (of a reference/box inside this compound value)
 --> src/main.rs:4:14
  |
4 |     let _z = y;
  |              ^
  = note: BACKTRACE (of the first span):
  = note: inside `main` at /playground/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/macros.rs:364:13: 364:16
  = note: this error originates in the macro `dbg` (in Nightly builds, run with -Z macro-backtrace for more info)

note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace

error: aborting due to 1 previous error

Wrapping the element using MaybeUninit (or MaybeDangling once we have that) should make this sound.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

A-boxArea: Our favorite opsem complicationC-bugCategory: This is a bug.I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessP-criticalCritical priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-libsRelevant to the library team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions