-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
trait_upcasting
unsoundness due to reordered super traits
#131813
Comments
hey rustbot: @rustbot label: +F-trait_upcasting +A-coercions +A-trait-objects +I-unsound +T-lang +T-types |
I would probably continue emitting vtables for ordinary traits which don't have any entries but instead make sure that we never emit any entries for auto traits. cc @compiler-errors @WaffleLapkin |
slightly minimized #![feature(trait_upcasting)]
trait Pollable {
#[allow(unused)]
fn poll(&self) {}
}
trait FileIo: Pollable + Send {
fn read(&self) {}
}
trait Terminal: Send + FileIo {}
struct A;
impl Pollable for A {}
impl FileIo for A {}
impl Terminal for A {}
fn main() {
let a = A;
let b = &a as &dyn Terminal;
let c = b as &dyn FileIo;
c.read();
} |
The specific issue has nothing to do with auto traits (although I mentioned them in the title and use it as an example throughout the issue description). Hope this is not misleading. If you replace the |
trait_upcasting
unsoundness due to reordered Send
/Sync
trait_upcasting
unsoundness due to reordered super traits
Okay, that's very good to know 👍 I thought it only impacted auto traits, moved that concern into a separate issue #131813 |
@WaffleLapkin Thanks for the confirmation! I opened at #131864. |
Rollup merge of rust-lang#131864 - lrh2000:upcast_reorder, r=WaffleLapkin Never emit `vptr` for empty/auto traits Emiting `vptr`s for empty/auto traits is unnecessary (rust-lang#114942) and causes unsoundness in `trait_upcasting` (rust-lang#131813). This PR should ensure that we never emit vtables for such traits. See the linked issues for more details. I'm not sure if I can add tests for the vtable layout. So this PR only adds tests for the soundness hole (i.e., the segmentation fault will disappear after this PR). Fixes rust-lang#114942 Fixes rust-lang#131813 Cc rust-lang#65991 (tracking issue for `trait_upcasting`) r? `@WaffleLapkin` (per rust-lang#131813 (comment))
The following program will trigger a segmentation fault. (playground link)
This is because the vtable layout of
Send + Sync + FileIo
(i.e., the supertrait ofTerminal
) is different from that ofFileIo
, even though (i)Send
andSync
are auto traits and (ii)FileIo
isSend
andSync
. However, it seems that the upcast coerion thinks they are the same, so it reuses the vtable, causing segmentation faults.vtables
I checked how the vtable layout is generated:
rust/compiler/rustc_trait_selection/src/traits/vtable.rs
Lines 157 to 168 in 798fb83
By the current implementation,
Send + Sync + FileIo
will not havevptr
s forSend
andSync
becauseSend
andSync
are iterated at the very first during theprepare_vtable_segments_inner
method. Soemit_vptr_on_new_entry
is false whenSend
andSync
are iterated.FileIo
will havevptr
s forSend
andSync
becauseSend
andSync
are iterated afterPollable
is iterated. This means thatprepare_vtable_segments_inner
is true whenSend
andSync
are iterated.This sounds a little strange to me.
Patch
I tried the following patch, which makes both
Send + Sync + FileIo
andFileIo
not havevptr
s forSend
andSync
. I confirmed that the reported problem disappears, but I don't know if I'm on the right track since I'm not familiar with the code. (I can open a PR if it sounds right).patch
Cc #65991 (tracking issue for
trait_upcasting
)@rustbot label +F-trait_upcasting +A-coercions +A-trait-objects +I-unsound +T-lang +T-type
The text was updated successfully, but these errors were encountered: