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
Warn when transmuting raw pointers #11734
Comments
cc @RalfJung, who might have opinions about when to fire the lint and what to suggest as an alternative. |
At least under our current models, transmuting between pointer types does preserve provenance. Transmuting from *mut T to *mut U is equivalent to a cast. I don't see that changing. Problems arise when transmuting between integers and pointers; transmuting between usize and *mut T is *not* equivalent to a cast.
|
A lint for this already exists, although is allowed by default: https://rust-lang.github.io/rust-clippy/master/index.html#/transmute_ptr_to_ptr |
Ah I see, I had misunderstood. What about transmuting references-to-pointers? Ie, does transmuting Your response confirms that zerocopy's |
TIL, thanks! Sounds like this can be closed. |
Provenance is always preserved wherever the output has pointer or reference type. (And inside |
Sorry, I meant "transmuting
Okay gotcha, so the fact that you're going |
Well, The general model is: whenever you are making a typed copy (such as assignment, passing arguments to a function, receiving the return value of a function), then the source memory is "de-serialized" into a "high-level representation" (like this one), and that high-level representation is then "serialized" into the target memory. This (a) means there is UB if the source memory does not represent any high-level value, such as trying to de-serialize
So when you transmute to/from integers, the data goes through a |
Yeah, I specifically meant "
I think I understand this model. IIUC, if it is the case that |
That sounds right, albeit expressed in somewhat complicated ways. Transmutation is a shallow operation, so transmuting Maybe you're concerned with what safe code does with the resulting value after the transmute happens? That's a much broader question, but then you have to consider the safety invariants as well obviously, not just whether provenance is preserved. |
What I'm more worried about is whether provenance on the inner pointer is preserved. E.g., if I perform |
The provenance of the inner pointer lives in memory. Transmuting does not change the contents of memory. So no there's no way this can affect the provenance of the inner pointer, just like transmuting
There's no "resulting *const U". There's a resulting |
Okay that clarifies it for me, thanks!
I think it's less about my mental model being different and more about it being less complete. In particular, it sounds like your model is that provenance lives inside of a pointer regardless of whether you're accessing that pointer as a local variable or via some kind of indirection. I didn't think that this wasn't the case, but rather I didn't have any belief about that fact one way or the other. Generally speaking, when it comes to the semantics of unsafe code, I've learned to assume that my mental model might be slightly wrong in various ways. Correspondingly, I've learned that if I make a logical deduction about what code will be sound on the basis of my mental model, there's a chance that that deduction will lead me to an incorrect conclusion. If you are 100% confident in your model, then you can confidently conclude that
In practice I know that none of these are true, but my point is just to illustrate that as someone who is trying to language-lawyer existing documentation written by other people, it can be dangerous to assume that you know anything at all 😛 |
Yes indeed. Local variables are also just places in memory, the indirection is managed automatically by the Abstract Machine. (See the definition of
That's fair. To be clear, I was not criticizing you, just expressing my surprise. It's a constant reminder how little we actually clearly document about provenance currently. |
No worries, I didn't take it as such 🙂
Yeah, and this is unfortunately something that demands an absurd level of precision and verbosity compared to "normal" module/type/function/etc documentation. |
What it does
Warns when calling
mem::transmute
ortransmute_copy
where the source or destination types contain raw pointers.Advantage
Transmuting is an operation which may not preserve provenance of raw pointers, and so represents a subtle footgun.
Drawbacks
There is not always an obvious alternative for Clippy to suggest. The suggestion may simply be something to the effect of "be careful about provenance."
In some specific cases, there may be an applicable suggestion such as the example given below, in which raw pointers are being directly transmuted (as opposed to types which recursively contains raw pointers).
Example
Could be written as:
The text was updated successfully, but these errors were encountered: