Skip to content

What are the guarantees over ZST pointers #503

Closed
@celinval

Description

@celinval

Hi, we've been trying to understand what's the correct way to model ZST pointers. What is UB and what has well defined behavior.

  1. Does a ZST pointer have provenance?
  2. Does ZST pointer identity hold?
  3. If it point to a ZST field in a structure, will it always be inbounds?
  4. Will the address of a static ZST always fall in the memory section of statics? Will the address of a local ZST always point to a location in the stack frame?
  5. Should a ZST pointer comparison take provenance into account or just the address?

Thanks!

Activity

Lokathor

Lokathor commented on Apr 9, 2024

@Lokathor
Contributor
  1. I think you mean "provenance", and yes technically they do.
  2. Not sure what you're asking. a == a will be true for a ZST pointer, if that's what you mean.
  3. A pointer to a field of a struct will be inbounds of the full struct, yeah.
  4. This is not guaranteed in any way. In fact, some people would like this to specifically not be the case so that ZST address values can be const folded.
  5. Pointer comparison doesn't compare provenance, just the address (and possibly more with a DST, but we'll ignore that for now). EDIT: see What are the guarantees over ZST pointers #503 (comment)
chorman0773

chorman0773 commented on Apr 9, 2024

@chorman0773
Contributor

For almost all purposes related to provenance, a pointer to a ZST is not distinct from a pointer to another type.
There are additional guarantees in terms of what operations are valid, when that operation is done with zero size. For example, memory accesses of zero size are trivially valid when well-aligned.

celinval

celinval commented on Apr 9, 2024

@celinval
Author
  1. I think you mean "provenance", and yes technically they do.

Sorry, my phone keeps auto correcting provenance for some reason. Or maybe it was my brain malfunction. 🤷🏻‍♀️

celinval

celinval commented on Apr 9, 2024

@celinval
Author
5. Pointer comparison doesn't compare provenance, just the address (and possibly more with a DST, but we'll ignore that for now).

I thought that was still up for debate from reading this issue: #239

RalfJung

RalfJung commented on Apr 10, 2024

@RalfJung
Member

For further information on provenance, see the RFC. The pointee type and being a reference vs a raw pointer makes no difference for provenance.

I thought that was still up for debate from reading this issue: #239

Yes, we haven't made an official t-lang decision on this. But at this point it seems unlikely that provenance will affect pointer comparison. The main unknown here is how to resolve #328.

On today's Rust, provenance does not affect pointer comparison.

Will the address of a static ZST always fall in the memory section of statics? Will the address of a local ZST always point to a location in the stack frame?

The Rust specification does not have a notion of memory sections for statics or stack frames. All allocated objects are placed at arbitrary locations in memory and there is no guarantee whatsoever that stack allocations are in "the stack" or Box allocations are on "the heap".


I think this answers all questions, or would you like further clarification?

tautschnig

tautschnig commented on Apr 10, 2024

@tautschnig

The Rust specification does not have a notion of memory sections for statics or stack frames. All allocated objects are placed at arbitrary locations in memory and there is no guarantee whatsoever that stack allocations are in "the stack" or Box allocations are on "the heap".

https://doc.rust-lang.org/reference/variables.html says that "A local variable (or stack-local allocation) holds a value directly, allocated within the stack's memory." (And https://doc.rust-lang.org/reference/memory-allocation-and-lifetime.html says something about Box and heap, but indeed does not promise that all Box allocations would be on the heap.)

RalfJung

RalfJung commented on Apr 10, 2024

@RalfJung
Member

That should be fixed then, these guarantees make no sense on the level of the Rust spec. Stack and heap as distinct parts of the address space are target-specific notions that do not exist in the Abstract Machine.

celinval

celinval commented on Apr 17, 2024

@celinval
Author

For example, memory accesses of zero size are trivially valid when well-aligned.

I think that would be a simple way to go about it, since these are no-op, but if I understand it correctly, a zero-size access is invalid if the pointer points to a deallocated memory, correct? I'm assuming that's because of provenance.

I am curious if provenance is also taken into account if the pointer is out-of-bounds of the original object? Would a zero-size access be valid in out-of-bounds pointers?

RalfJung

RalfJung commented on Apr 17, 2024

@RalfJung
Member

if I understand it correctly, a zero-size access is invalid if the pointer points to a deallocated memory, correct? I'm assuming that's because of provenance.

This used to be the case but we decided to change it and allow more code. See rust-lang/rust#117945. Once that is fully implemented, zero-sized accesses will ignore provenance.

I am curious if provenance is also taken into account if the pointer is out-of-bounds of the original object? Would a zero-size access be valid in out-of-bounds pointers?

Under the current rules as implemented by Miri today, that would be UB. But rust-lang/rust#117945 will make it allowed.

celinval

celinval commented on Apr 17, 2024

@celinval
Author

I think this answers all my questions. Thank you!

RalfJung

RalfJung commented on Apr 17, 2024

@RalfJung
Member

Sure, happy to help. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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

        Participants

        @RalfJung@tautschnig@chorman0773@Lokathor@celinval

        Issue actions

          What are the guarantees over ZST pointers · Issue #503 · rust-lang/unsafe-code-guidelines