Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: transmute<&mut T, &mut MaybeUninit<T>> is unsound when exposed to safe code #134583

Merged
merged 1 commit into from
Dec 23, 2024

Conversation

Enselic
Copy link
Member

@Enselic Enselic commented Dec 20, 2024

Closes #66699

On my system (Edit: And also in the playground) the example program terminates with an unpredictable exit code:

$ cargo +nightly build && target/debug/bin ; echo $?
255
$ cargo +nightly build && target/debug/bin ; echo $?
253

And miri considers the code to have undefined behavior:

$ cargo +nightly miri run
error: Undefined Behavior: using uninitialized data, but this operation requires initialized memory
  --> src/main.rs:12:24
   |
12 |     std::process::exit(*code); // UB! Accessing uninitialized memory
   |                        ^^^^^ using uninitialized data, but this operation requires initialized memory
   |
error: aborting due to 1 previous error

@rustbot
Copy link
Collaborator

rustbot commented Dec 20, 2024

r? @workingjubilee

rustbot has assigned @workingjubilee.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Dec 20, 2024
///
/// Note that even though `MaybeUninit<T>` and `T` are ABI compatible it is still unsound to
/// transmute `&mut T` to `&mut MaybeUninit<T>` because that would enable safe Rust to access
/// uninitialized memory:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reasoning only tells me why exposing a &mut MaybeUninit<T> from an arbitrary &mut T is unsafe, not that it's always unsound to do that reinterpretation.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I don't think this is the right place to put this warning. Though I'm not sure where the right place is. Maybe on MaybeUninit itself?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is MaybeUninit itself?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, lol. yeah then only the wording should be changed

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, I wouldn't say "unsound" because unsafe code inherently can perform this sort of rule-bending feat without it immediately unsound, that's the point of unsafe code... but you do have to restore the invariants before you release control to code that isn't "in on it".

Copy link
Member Author

@Enselic Enselic Dec 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for quick review.

According to the reference:

if unsafe code can be misused by safe code to exhibit undefined behavior, it is unsound.

so I think this rewording is accurate:

/// Note that even though `T` and `MaybeUninit<T>` are ABI compatible it is still unsound to
/// transmute `&mut T` to `&mut MaybeUninit<T>` and expose that to safe code because it would allow
/// safe code to access uninitialized memory:

Does anyone disagree?

Here is how that looks when rendered to make it easier to get a feel for it:

image

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, that seems fine.

@Enselic Enselic changed the title core: Document that transmute<&mut T, &mut MaybeUninit<T>> is unsound core: Document that transmute<&mut T, &mut MaybeUninit<T>> is unsound with safe code Dec 21, 2024
@Enselic Enselic changed the title core: Document that transmute<&mut T, &mut MaybeUninit<T>> is unsound with safe code core: docs: transmute<&mut T, &mut MaybeUninit<T>> is unsound when exposed to safe code Dec 21, 2024
…d to safe code

In the playground the example program terminates with an unpredictable exit
code. The undefined behavior is also detected by miri:

    error: Undefined Behavior: using uninitialized data
@Enselic Enselic force-pushed the maybe-uninit-transmute branch from 3b8b8ad to 2305012 Compare December 22, 2024 13:23
@Enselic Enselic changed the title core: docs: transmute<&mut T, &mut MaybeUninit<T>> is unsound when exposed to safe code docs: transmute<&mut T, &mut MaybeUninit<T>> is unsound when exposed to safe code Dec 22, 2024
@workingjubilee
Copy link
Member

@bors r+ rollup

@bors
Copy link
Contributor

bors commented Dec 22, 2024

📌 Commit 2305012 has been approved by workingjubilee

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Dec 22, 2024
bors added a commit to rust-lang-ci/rust that referenced this pull request Dec 22, 2024
…iaskrgr

Rollup of 6 pull requests

Successful merges:

 - rust-lang#130289 (docs: Permissions.readonly() also ignores root user special permissions)
 - rust-lang#134583 (docs: `transmute<&mut T, &mut MaybeUninit<T>>` is unsound when exposed to safe code)
 - rust-lang#134611 (Align `{i686,x86_64}-win7-windows-msvc` to their parent targets)
 - rust-lang#134629 (compiletest: Allow using a specific debugger when running debuginfo tests)
 - rust-lang#134642 (Implement `PointerLike` for `isize`, `NonNull`, `Cell`, `UnsafeCell`, and `SyncUnsafeCell`.)
 - rust-lang#134660 (Fix spacing of markdown code block fences in compiler rustdoc)

r? `@ghost`
`@rustbot` modify labels: rollup
bors added a commit to rust-lang-ci/rust that referenced this pull request Dec 23, 2024
…iaskrgr

Rollup of 6 pull requests

Successful merges:

 - rust-lang#130289 (docs: Permissions.readonly() also ignores root user special permissions)
 - rust-lang#134583 (docs: `transmute<&mut T, &mut MaybeUninit<T>>` is unsound when exposed to safe code)
 - rust-lang#134611 (Align `{i686,x86_64}-win7-windows-msvc` to their parent targets)
 - rust-lang#134629 (compiletest: Allow using a specific debugger when running debuginfo tests)
 - rust-lang#134642 (Implement `PointerLike` for `isize`, `NonNull`, `Cell`, `UnsafeCell`, and `SyncUnsafeCell`.)
 - rust-lang#134660 (Fix spacing of markdown code block fences in compiler rustdoc)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 6ade237 into rust-lang:master Dec 23, 2024
6 checks passed
@rustbot rustbot added this to the 1.85.0 milestone Dec 23, 2024
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Dec 23, 2024
Rollup merge of rust-lang#134583 - Enselic:maybe-uninit-transmute, r=workingjubilee

docs: `transmute<&mut T, &mut MaybeUninit<T>>` is unsound when exposed to safe code

Closes rust-lang#66699

On my system (Edit: And also in the [playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=90529e2a9900599cb759e4bfaa5b5efe)) the example program terminates with an unpredictable exit code:
```console
$ cargo +nightly build && target/debug/bin ; echo $?
255
$ cargo +nightly build && target/debug/bin ; echo $?
253
```

And miri considers the code to have undefined behavior:
```console
$ cargo +nightly miri run
error: Undefined Behavior: using uninitialized data, but this operation requires initialized memory
  --> src/main.rs:12:24
   |
12 |     std::process::exit(*code); // UB! Accessing uninitialized memory
   |                        ^^^^^ using uninitialized data, but this operation requires initialized memory
   |
error: aborting due to 1 previous error
```
@Enselic Enselic deleted the maybe-uninit-transmute branch December 23, 2024 04:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-libs Relevant to the library team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Document that casting &mut T to &mut MaybeUninit<T> is not safe
6 participants