Skip to content

Is it sound to check whether the bytes of an Option<&T> are zero? #488

Open
@joshlf

Description

@joshlf

Co-authored with @jswrenn.

In zerocopy, we have a situation where we have a *const Option<&T>. We know that the referent bytes are "as initialized" as the bytes of an Option<&T>, but not necessarily that they are a bit-valid Option<&T>. By "as initialized", we mean that one of the two is true:

  • The referent is a bit-valid Option::<&T>::None
  • The referent's discriminant represents Some, and its bytes are initialized wherever &T's bytes are initialized

What we need to do is check whether the referent contains all zeroed bytes. If it does, we can soundly treat those bytes as containing a Option::<&T>::None thanks to the NPO (which guarantees the layout of this specific value).

Our problem is this: We're not sure whether it's sound to look at all of the bytes (in other words, to transmute from Option<&T> to [u8; size_of::<Option<&T>>()]) in order to check that they're all zero. Another option we considered was round-tripping via Option<NonNull<T>> and then using NonNull::addr to extract the address.

Any guidance on whether transmuting Option<&T> to either [u8; size_of::<Option<&T>>()] or to Option<NonNull<T>> are sound?

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