-
-
Notifications
You must be signed in to change notification settings - Fork 14.8k
Pointer casts allow switching trait parameters for trait objects, which doesn’t interact soundly with trait upcasting #120222
Copy link
Copy link
Closed
Labels
A-coercionsArea: implicit and explicit `expr as Type` coercionsArea: implicit and explicit `expr as Type` coercionsA-dyn-traitArea: trait objects, vtable layoutArea: trait objects, vtable layoutC-bugCategory: This is a bug.Category: This is a bug.F-trait_upcasting`#![feature(trait_upcasting)]``#![feature(trait_upcasting)]`I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessT-langRelevant to the language teamRelevant to the language teamT-typesRelevant to the types team, which will review and decide on the PR/issue.Relevant to the types team, which will review and decide on the PR/issue.requires-nightlyThis issue requires a nightly compiler in some way. When possible, use a F-* label instead.This issue requires a nightly compiler in some way. When possible, use a F-* label instead.
Metadata
Metadata
Assignees
Labels
A-coercionsArea: implicit and explicit `expr as Type` coercionsArea: implicit and explicit `expr as Type` coercionsA-dyn-traitArea: trait objects, vtable layoutArea: trait objects, vtable layoutC-bugCategory: This is a bug.Category: This is a bug.F-trait_upcasting`#![feature(trait_upcasting)]``#![feature(trait_upcasting)]`I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessT-langRelevant to the language teamRelevant to the language teamT-typesRelevant to the types team, which will review and decide on the PR/issue.Relevant to the types team, which will review and decide on the PR/issue.requires-nightlyThis issue requires a nightly compiler in some way. When possible, use a F-* label instead.This issue requires a nightly compiler in some way. When possible, use a F-* label instead.
Type
Fields
Give feedbackNo fields configured for issues without a type.
Pointer casts allow switching trait parameters for trait objects, which can change the set of supertraits (and thus the vtable layout), ultimately making upcasting of raw pointers quite unsound
This code reproduces a segfault, on upcoming stable Rust, starting in
1.76(stabilization of trait object upcasting).Update: Stabilization was reverted,
1.76stable Rust is good, the below code examples needs nightly Rust and#[feature(trait_upcasting)]now.(playground, compiler explorer)
This issue exists next to #120217, but here I’ve found how the issue of overly liberal casting of raw pointers can be made into a concrete soundness issue, using no feature flags, producing an actual segfault.
Whether or now we need (to keep) two separate & somewhat similar GitHub issues can probably become clear eventually. If we don’t, we can always close one or the other.
Miri will already complain with a less sophisticated setup:
(playground)
Three possible ways of fixing this would be to
arbitrary_self_typesreceiver…)11.2, so some potential breakage and/or transition period, …!?)I’m marking as regression in beta as this is newly introduced unsoundness; and an approach like temporarily removing raw pointers again from our upcasting feature (assuming that’s technically possible in the first place) and/or delaying the stabilization are options, in case this soundness issue is perceived as sufficiently relevant not to be “ignored”.
@rustbot label +regression-from-stable-to-beta +F-trait_upcasting +A-coercions +A-trait-objects +I-unsound
Footnotes
my thought here is that e.g. it seems like missing methods are replaced with zeroes already, too, instead of skipped, and that pattern could be extended so that in the case of different sets of supertraits (like the
Super<u8>==Super<u8> + Super<u8>vs.Super<u8> + Super<u16>above) could thus perhaps also avoid supertrait pointers appearing in inconsistent places between an applied trait constructor [Trait<Args1…>vsTraits<Args2…>] with different parameters ↩