Skip to content

Do the bytes of a pointer have to stay in the same order? #558

Description

@RalfJung

There's another aspect of provenance that we haven't officially decided yet and that is implicitly answered by the current wording in rust-lang/reference#1664: do the individual bytes in a pointer "remember" where in the pointer they are, and have to be put back in the same order? Some formal models require this, and if we ever allow "taking apart" the bytes of a pointer in const-eval (rust-lang/const-eval#72) we'll also have to require this, but for runtime semantics we could decide either way.

The one example of code that I am aware of that breaks this requirement is XOR linked lists, which can be implemented in the semantics sketched in MiniRust right now but can't be implemented if bytes with provenance remember their position in the pointer. That's not exactly realistic code, but it is somewhat satisfying that (on architectures where pointers have at least 2 bytes), XOR linked lists can be implemented.

The main upside of requiring the same bytes in the same order is that it rules out pointer crimes like XOR linked lists so if there's some unexpected interactions there, we'd not be affected. It would also make the runtime semantics more consistent with the const-eval semantics. I am not aware of an optimization that would benefit from this UB, it's mostly a case of "ruling out some rather cursed programs to avoid locking ourselves into an unexpected corner". In some sense the model becomes a bit simpler since we can just say, pointer bytes must be put back together in the same order they started out as before they can be treated as a pointer again, but the actual op.sem would become more complicated because of the extra bookkeeping required to enforce this.

Activity

  1. added
    A-provenanceTopic: Related to when which values have which provenance (but not which alias restrictions follow)
    on Feb 20, 2025
  2. chorman0773 commented on Feb 22, 2025

    @chorman0773
    Contributor

    I'd certainly agree that ruling out pointer crimes is an upside 😛.

    In a more serious argument, I think it shouldn't be difficult to track this along with the Pointer. The only thing would be that Pointer would need to be something more like PointerFragment and be different between bytes (but this is really only an u8 is 0..size_of::<usize>() extra state). We could then say that if a pointer is computed from provenance, where the provenance isn't coherent (different provenances, wrong place, or some having no provenance) you get a pointer without provenance.

  3. RalfJung commented on Feb 22, 2025

    @RalfJung
    MemberAuthor

    No, it's not difficult, but it is extra complexity.

  4. madsmtm commented on Apr 14, 2025

    @madsmtm
    Member

    Since you mention XOR linked lists: I recently read the paper Garbage Collection for Rust: The Finalizer Frontier which implements a fork of Rust, and which also do not support such types.

    They implement GC by stopping the world and scanning the process memory, which is fraught with peril for many reasons, but still thought I'd note it as a possible use-case for restricting the bytes of pointers.

  5. added a commit that references this issue on Jul 17, 2025
  6. added a commit that references this issue on Aug 17, 2025
  7. added 2 commits that reference this issue on Nov 8, 2025
  8. 7 remaining items

  9. rust-rfcbot commented on Jul 21, 2026

    @rust-rfcbot
    Collaborator

    @RalfJung has proposed to merge this. The next step is review by the rest of the tagged team members:

    No concerns currently listed.

    Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

    See this document for info about what commands tagged team members can give me.

  10. rust-rfcbot commented on Jul 21, 2026

    @rust-rfcbot
    Collaborator

    🔔 This is now entering its final comment period, as per the review above. 🔔

  11. chorman0773 commented on Jul 21, 2026

    @chorman0773
    Contributor

    This was talked about today in the T-opsem meeting. The meeting was fine with the FCP going ahead, with a clarification.

    The rules proposed here will be enforced on typed copy - doing a typed load of a pointer with "broken" pointer bytes (not all bytes from one allocation, or not in the right order) produces a pointer with no provenance (similar to what you get with core::ptr::without_provenance). This is as opposed to allowing pointer values to carry arround a broken provenance state, and only be checked (causing UB) on dereference/add.
    Pointer "values" in a broken state can still be carried using MaybeUninit.

  12. joshlf commented on Jul 21, 2026

    @joshlf

    This was talked about today in the T-opsem meeting. The meeting was fine with the FCP going ahead, with a clarification.

    The rules proposed here will be enforced on typed copy - doing a typed load of a pointer with "broken" pointer bytes (not all bytes from one allocation, or not in the right order) produces a pointer with no provenance (similar to what you get with core::ptr::without_provenance). This is as opposed to allowing pointer values to carry arround a broken provenance state, and only be checked (causing UB) on dereference/add. Pointer "values" in a broken state can still be carried using MaybeUninit.

    To clarify: While the rules proposed here will be enforced on typed copy, they will not be enforced on byte copy (e.g. when copying via [MaybeUninit<u8>; N]). Thus, it will remain sound to do things like convert a raw pointer type, P, to a [MaybeUninit<u8>; size_of::<P>()], mix the bytes around, store them in various places, etc, as long as they end up back in their original order before being converted back to a P - in this case, the P will retain its original provenance.

  13. rust-rfcbot commented on Jul 31, 2026

    @rust-rfcbot
    Collaborator

    The final comment period, with a disposition to merge, as per the review above, is now complete.

    As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed.

  14. added a commit that references this issue on Aug 31, 2026
  15. added a commit that references this issue on Sep 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions