Skip to content

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

Open
@kupiakos

Description

@kupiakos

Progress


These days, MaybeUninit::zeroed is pretty clear that you cannot expect all padding bytes to be zero in the output value (same for mem::zeroed). Zerocopy mentions this, 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 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 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions