Skip to content

Guarantee allocations do not wrap around the address space - #155372

Open
iximeow wants to merge 2 commits into
rust-lang:mainfrom
iximeow:allocation-size-type
Open

iximeow wants to merge 2 commits into
rust-lang:mainfrom
iximeow:allocation-size-type

Conversation

@iximeow

@iximeow iximeow commented Apr 16, 2026 •

Copy link
Copy Markdown
Contributor

This was noted off-handedly in #116675 where this section was reworked. It seems worthwhile to note explicitly that an allocation's base and size are not "usize" or "isize" but infinitely-wide types where <= usize::MAX cannot be trivially assumed.

I got here trying to figure out if/why with_exposed_provenance::<(u8, u8)>(usize::MAX) returns an invalid *const T. either base + size <= usize::MAX is trivially true, or there's an assumption of wider-than-usize arithmetic and the answer is "it's invalid". seems like the latter, thank goodness! this was discussed in a few places in #116675 (this other comment for example) but ended up left to a careful reader in the landed docs.

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Apr 16, 2026
@rustbot

rustbot commented Apr 16, 2026

Copy link
Copy Markdown
Collaborator

r? @Mark-Simulacrum

rustbot has assigned @Mark-Simulacrum.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: @scottmcm, libs
  • @scottmcm, libs expanded to 7 candidates
  • Random selection from Mark-Simulacrum, jhpratt, scottmcm

@rustbot

This comment has been minimized.

This was noted off-handedly in the PR discussion where this section was
reworked.  It seems worthwhile to note explicitly that an allocation's
base and size are not "usize" or "isize" but infinitely-wide types where
`<= usize::MAX` cannot be trivially assumed.
@iximeow
iximeow force-pushed the allocation-size-type branch from 0179fce to 61da6d3 Compare April 16, 2026 01:36
@iximeow

iximeow commented Apr 16, 2026

Copy link
Copy Markdown
Contributor Author

thank u rustbot

@saethlin

Copy link
Copy Markdown
Member

I don't know what you mean by infinite-precision. I'm not sure we've ever used that terminology with regard to provenance, is there another way to express what you mean?

If someone does call with_exposed_provenance(usize::MAX), since there cannot be any allocations at usize::MAX, the assumption is that if the pointer is used later in a way that requires provenance, that it will have its address moved into range using with_addr/map_addr/wrapping_offset.

@iximeow

iximeow commented Apr 16, 2026

Copy link
Copy Markdown
Contributor Author

this is more about "can an allocation wrap across the end of the address space" than anything about provenance; I only mention with_exposed_provenance because the only way I could even try coming up with an argument about such an allocation would be to say "outside of Rust I know there is an allocation at 0xff..fff000..u64::MAX and 0..0xfff" and the Ralf in my head would be very irritated at just casting numbers to pointers.

infinite-precision refers to base and size in the docs - if they are usize types then base + size <= usize::MAX is always true and according to the rules laid out in std::ptr Allocation then why couldn't an allocation start at usize::MAX - 1, be four bytes long, and wrap to the start of address space? either way I hope this is more obvious from the diff alone than when it's muddied with my PR description?

since there cannot be any allocations at usize::MAX,

couldn't there be a ZST there? (though also since base + size <= usize::MAX, that implies that an allocation cannot happen to have a byte at usize::MAX..?)

@saethlin

Copy link
Copy Markdown
Member

I see. I think it would be less confusing to add a note that none of the arithmetic wraps. At least it would have been easier for my brain because that's a term we already use in this space.

@iximeow

iximeow commented Apr 16, 2026

Copy link
Copy Markdown
Contributor Author

I've adjusted the wording a bit differently, any time I tried to describe it as non-wrapping arithmetic it felt a bit hamfisted.. but in the "As a consequence ..." section we've already described the idea that sums do not wrap the address space. so I think it reads better to pull that up to talk about base + size, expand on the idea there, and repeat that same phrasing below for base + o. at least to me I think this reads better than appealing to infinite-precision arithmetic too?

does this read better to you as well?

@Mark-Simulacrum Mark-Simulacrum changed the title Note infinite-precision in std::ptr Allocation docs Guarantee allocations do not wrap around the address space Apr 18, 2026
@Mark-Simulacrum

Copy link
Copy Markdown
Member

r? @saethlin but I think I'm happy with the in-PR wording (but don't feel strongly that this needs mentioning here)

@rustbot rustbot assigned saethlin and unassigned Mark-Simulacrum Apr 18, 2026
@saethlin

Copy link
Copy Markdown
Member

@iximeow Well, this reads better to me than your initial proposal, but I also don't see how this is an improvement over what's already in the repo. But if you think it is an improvement, I'm happy to merge it.

@clarfonthey clarfonthey added the T-opsem Relevant to the opsem team label Sep 17, 2026
//! - `base` is not equal to [`null()`] (i.e., the address with the numerical
//! value 0)
//! - `base + size <= usize::MAX`
//! - `base + size <= usize::MAX`; `base + size` will not wrap around the

@RalfJung RalfJung Sep 18, 2026 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The meaning of the semicolon here is unclear to me -- is this meant to clarify the first part, or to impose further restrictions?

View changes since the review

@iximeow iximeow Sep 20, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

admittedly I've struggled with how to phrase this. when I read https://doc.rust-lang.org/core/ptr/index.html in April I did not immediately realize that + means "under arbitrary-precision" or "bignum" or "infinite-precision" or term-of-choice. instead, I'd understood it as "base and size are usize" since that is the representation of an address and return value of std::mem::size_of().

if you read these as arbitrary-precision, then this just clarifies the first part. if you read these as usize, as I would suggest most readers probably will without explicit guidance, this section is correct except for needing this further restriction that base + size does not wrap.

I would rather address it by expressing specifically that the arithmetic here is arbitrary-precision (as I tried in the first diff, but the phrasing reads poorly and I couldn't figure out how to resolve it directly. several functions in the module (repeatedly) say computed on mathematical integers, so it feels like there should be a stanza for the module about how math on pointers and offsets is described wit large that the module generally agrees on. or at least we should introduce that phrase earlier than in the docs of eight functions that give you a pointer with a different address.

more than you asked for, sorry - hopefully that makes sense?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We did indeed mean a mathematical + here. I don't agree with your assessment that most readers will assume a wrapping +, but I admit that some readers could interpret the text like that. That does make the entire condition completely pointless so I assume most people would notice, but maybe we can find a way to be more explicit.

Comment on lines +132 to +133
//! - `base + size <= usize::MAX`; `base + size` will not wrap around the
//! address space (in other words, will not overflow)

@RalfJung RalfJung Sep 20, 2026 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
//! - `base + size <= usize::MAX`; `base + size` will not wrap around the
//! address space (in other words, will not overflow)
//! - `base + size <= usize::MAX` (computed on mathematical integers)

This follows the precedent in https://doc.rust-lang.org/nightly/std/primitive.pointer.html#method.offset

View changes since the review

This branch has not been deployed

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

Labels

S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. T-opsem Relevant to the opsem team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants