-
Notifications
You must be signed in to change notification settings - Fork 13.2k
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
Safe Transmute: Require that source referent is smaller than destination #122438
Conversation
} else if dst_ref.size() > src_ref.size() { | ||
Answer::No(Reason::DstRefIsTooBig { | ||
src: src_ref, | ||
dst: src_ref, | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(This is the critical change of the PR.)
@@ -81,6 +92,16 @@ pub mod rustc { | |||
} | |||
impl<'tcx> Ref<'tcx> {} | |||
|
|||
impl<'tcx> fmt::Display for Ref<'tcx> { | |||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |||
f.write_char('&')?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not printing the region here too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could, but it's not relevant to the error message this Display
routine is currently used in, and I don't anticipate it will be relevant to other transmute error messages, since regions do not impact layout.
let src_size = src.size; | ||
let dst_size = dst.size; | ||
format!( | ||
"The referent size of `{src}` ({src_size} bytes) is smaller than that of `{dst}` ({dst_size} bytes" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"The referent size of `{src}` ({src_size} bytes) is smaller than that of `{dst}` ({dst_size} bytes" | |
"The referent size of `{src}` ({src_size} bytes) is smaller than that of `{dst}` ({dst_size} bytes)" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
b949a37
to
107a473
Compare
--> $DIR/unit-to-u8.rs:22:52 | ||
| | ||
LL | assert::is_maybe_transmutable::<&'static Unit, &'static u8>(); | ||
| ^^^^^^^^^^^ The size of `Unit` is smaller than the size of `u8` | ||
| ^^^^^^^^^^^ The referent size of `&Unit` (0 bytes) is smaller than that of `&Unit` (0) bytes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This still doesn't look right 😆
| ^^^^^^^^^^^ The referent size of `&Unit` (0 bytes) is smaller than that of `&Unit` (0) bytes | |
| ^^^^^^^^^^^ The referent size of `&Unit` (0 bytes) is smaller than that of `&Unit` (0 bytes) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oof, I need to sleep more.
107a473
to
422fb2e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please triple check the error messages.
} else if dst_ref.size() > src_ref.size() { | ||
Answer::No(Reason::DstRefIsTooBig { | ||
src: src_ref, | ||
dst: src_ref, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dst: src_ref, | |
dst: dst_ref, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
The source referent absolutely must be smaller than the destination referent of a ref-to-ref transmute; the excess bytes referenced cannot arise from thin air, even if those bytes are uninitialized.
422fb2e
to
216df4a
Compare
error[E0277]: `&Packed<Two>` cannot be safely transmuted into `&Packed<Four>` | ||
--> $DIR/reject_extension.rs:48:37 | ||
| | ||
LL | assert::is_transmutable::<&Src, &Dst>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like that only the second parameter is ^^^^
, but that's a general issue with all of our error messages that I'll file a follow-up PR for.
Otherwise, this error message LGTM.
@bors r+ rollup |
…iaskrgr Rollup of 11 pull requests Successful merges: - rust-lang#122422 (compiletest: Allow `only-unix` in test headers) - rust-lang#122424 (fix: typos) - rust-lang#122425 (Increase timeout for new bors bot) - rust-lang#122426 (Fix StableMIR `WrappingRange::is_full` computation) - rust-lang#122429 (Add Exploit Mitigations PG to triagebot.toml) - rust-lang#122430 (Generate link to `Local` in `hir::Let` documentation) - rust-lang#122434 (pattern analysis: rename a few types) - rust-lang#122437 (pattern analysis: remove `MaybeInfiniteInt::JustAfterMax`) - rust-lang#122438 (Safe Transmute: Require that source referent is smaller than destination) - rust-lang#122442 (extend docs of -Zprint-mono-items) - rust-lang#122449 (Delay a bug for stranded opaques) r? `@ghost` `@rustbot` modify labels: rollup
…iaskrgr Rollup of 11 pull requests Successful merges: - rust-lang#122422 (compiletest: Allow `only-unix` in test headers) - rust-lang#122424 (fix: typos) - rust-lang#122425 (Increase timeout for new bors bot) - rust-lang#122426 (Fix StableMIR `WrappingRange::is_full` computation) - rust-lang#122429 (Add Exploit Mitigations PG to triagebot.toml) - rust-lang#122430 (Generate link to `Local` in `hir::Let` documentation) - rust-lang#122434 (pattern analysis: rename a few types) - rust-lang#122437 (pattern analysis: remove `MaybeInfiniteInt::JustAfterMax`) - rust-lang#122438 (Safe Transmute: Require that source referent is smaller than destination) - rust-lang#122442 (extend docs of -Zprint-mono-items) - rust-lang#122449 (Delay a bug for stranded opaques) r? `@ghost` `@rustbot` modify labels: rollup
Rollup merge of rust-lang#122438 - jswrenn:check-referent-size, r=compiler-errors Safe Transmute: Require that source referent is smaller than destination `BikeshedIntrinsicFrom` currently models transmute-via-union; i.e., it attempts to provide a `where` bound for this function: ```rust pub unsafe fn transmute_via_union<Src, Dst>(src: Src) -> Dst { use core::mem::*; #[repr(C)] union Transmute<T, U> { src: ManuallyDrop<T>, dst: ManuallyDrop<U>, } let transmute = Transmute { src: ManuallyDrop::new(src) }; // SAFETY: The caller must guarantee that the transmutation is safe. let dst = transmute.dst; ManuallyDrop::into_inner(dst) } ``` A quirk of this model is that it admits padding extensions in value-to-value transmutation: The destination type can be bigger than the source type, so long as the excess consists of uninitialized bytes. However, this isn't permissible for reference-to-reference transmutations (introduced in rust-lang#110662) — extra referent bytes cannot come from thin air. This PR patches our analysis for reference-to-reference transmutations to require that the destination referent is no larger than the source referent. r? `@compiler-errors`
BikeshedIntrinsicFrom
currently models transmute-via-union; i.e., it attempts to provide awhere
bound for this function:A quirk of this model is that it admits padding extensions in value-to-value transmutation: The destination type can be bigger than the source type, so long as the excess consists of uninitialized bytes. However, this isn't permissible for reference-to-reference transmutations (introduced in #110662) — extra referent bytes cannot come from thin air.
This PR patches our analysis for reference-to-reference transmutations to require that the destination referent is no larger than the source referent.
r? @compiler-errors