google / google/zerocopy

Transmuting `&mut MaybeUninit::zeroed()` to `&mut [u8]` is unsound

Open
#2,319 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
2.6k
Forks
179
Avg merge
1d 19h
Merged PRs (30d)
29

Description

## Progress
- [x] Fix unsoundness in `FromBytes::read_from_io`
- #2320
- #2358
- [ ] Update documentation as described below

---

These days, `MaybeUninit::zeroed` is [pretty clear](https://doc.rust-lang.org/std/mem/union.MaybeUninit.html#method.zeroed) that you cannot expect all padding bytes to be zero in the output value (same for [`mem::zeroed`](https://doc.rust-lang.org/std/mem/fn.zeroed.html)). Zerocopy [mentions this](https://docs.rs/zerocopy/latest/zerocopy/trait.FromZeros.html#warning-padding-bytes), but it doesn't seem fully internalized by the library:

- `FromZeros::zero` contradicts this, stating that it's similar to `*self = Self::new_zeroed()` and that the difference is it doesn't semantically drop anything. This isn't the only difference! `zero` is capable of fully zeroing all of the bytes of an object until it is moved into, while `*self = Self::new_zeroed()` doesn't guarantee you can then soundly access as a byte slice unless that `Self: IntoBytes`.
- `FromZeros::new_zeroed` doesn't mention the same caveat as `MaybeUninit::zeroed` at all even though it applies.
- The [current implementation](https://github.com/google/zerocopy/blob/17e7e4d98c9d2cd49c94307e2276b7ce377aa74a/src/lib.rs#L4551) of `FromBytes::read_from_io` is unsound, since there may still be padding bytes for `!IntoBytes` types from `new_zeroed`. It should be constructing a `MaybeUninit::uninit()` then [zeroing its bytes](https://doc.rust-lang.org/std/ptr/fn.write_bytes.html) before casting to `&mut [u8]`.

I'll send a PR fixing the unsoundness issue. I'm also interested in improving the documentation to be more consistent and to provide clear working alternatives to documented unsound operations.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.