Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Should not use transmute to cast between pointers and integers #288

Closed
programmerjake opened this issue Jun 23, 2022 · 10 comments
Closed

Should not use transmute to cast between pointers and integers #288

programmerjake opened this issue Jun 23, 2022 · 10 comments
Labels
C-bug Category: Bug I-unsound💥 Warning! Warning! Danger

Comments

@programmerjake
Copy link
Member

programmerjake commented Jun 23, 2022

Pointer to integer transmutes are almost certainly UB if you want to convert the resulting integer to a valid pointer again...you need a explicit pointer cast operation instead.
rust-lang/unsafe-code-guidelines#286

imho integer to pointer transmutes should be avoided too (even though they aren't necessarily UB), to go along with avoiding pointer to integer transmutes.

See also: #287

@programmerjake programmerjake added C-bug Category: Bug I-unsound💥 Warning! Warning! Danger labels Jun 23, 2022
@calebzulawski
Copy link
Member

calebzulawski commented Jun 23, 2022

There's nothing wrong with actually casting (or transmuting) pointers, just using them. My understanding is that ptr as isize as *const T can't be dereferenced; there's nothing special about as vs transmute.

@Lokathor
Copy link
Contributor

there is though

@calebzulawski
Copy link
Member

calebzulawski commented Jun 23, 2022

Is there? as uses inttoptr, but it doesn't add the dereferenceable metadata. I agree we should use a cast intrinsic (for better codegen and readability), but either way there is no impact on provenance. rust-lang/rust#95228 calls out int as ptr as also being invalid.

@calebzulawski
Copy link
Member

As far as I can tell, only with_addr or some wrapping_offset games are the only ways to make valid dereferenceable pointers out of integers--no cast will do it.

@thomcc
Copy link
Member

thomcc commented Jun 23, 2022

ptr as int is ptr::expose_addr, which exposes the pointer. On platforms that allow it (which doesn't include inside miri, and may not include CHERI), if you haven't violated that provenance, this may allow converting back to the original pointer with the opposite as cast.

@calebzulawski
Copy link
Member

calebzulawski commented Jun 23, 2022

Interesting. That must be the distinction I missed. Does LLVM even support this? The tracking issue for strict provenance implies this isn't valid at all, but I suppose this is saying that violating strict provenance isn't necessarily UB.

@programmerjake
Copy link
Member Author

Interesting. That must be the distinction I missed. Does LLVM even support this?

yes. casting int <-> ptr has been part of C for years...iirc it is part of the original C spec.

The tracking issue for strict provenance implies this isn't valid at all, but I suppose this is saying that violating strict provenance isn't necessarily UB.

yes, strict provenance is intended to codify a simple-to-understand useful subset of what's considered valid -- int <-> pointer casting currently has ill-defined semantics -- C is currently trying to decide which formal model they use to describe it.

@calebzulawski
Copy link
Member

Opened rust-lang/rust#98441

@RalfJung
Copy link
Member

RalfJung commented Jul 2, 2022

ptr as int is ptr::expose_addr, which exposes the pointer. On platforms that allow it (which doesn't include inside miri, and may not include CHERI), if you haven't violated that provenance, this may allow converting back to the original pointer with the opposite as cast.

FWIW, Miri actually does support this, but you lose precision -- as in, Miri might miss some UB when you do that.

Does LLVM even support this?

LLVM does not say what its ptr2int and int2ptr cast and transmute semantics are. And the implied semantics (by observing what optimizations do) are inconsistent -- they turn well-defined programs into UB.
So, looking to LLVM for guidance here is futile.

See my recent blog post for a lot more details on all that.

@calebzulawski
Copy link
Member

Fixed in #287

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: Bug I-unsound💥 Warning! Warning! Danger
Projects
None yet
Development

No branches or pull requests

5 participants