-
Notifications
You must be signed in to change notification settings - Fork 14.1k
Open
Labels
C-bugCategory: This is a bug.Category: This is a bug.E-needs-mcveCall for participation: This issue has a repro, but needs a Minimal Complete and Verifiable ExampleCall for participation: This issue has a repro, but needs a Minimal Complete and Verifiable ExampleF-coerce_unsizedThe `CoerceUnsized` traitThe `CoerceUnsized` traitI-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/SoundnessP-mediumMedium priorityMedium priorityT-langRelevant to the language teamRelevant to the language teamrequires-nightlyThis issue requires a nightly compiler in some way.This issue requires a nightly compiler in some way.
Description
Split out from #66544. It is possible to exploit Pin on nightly Rust (but not stable) by creating smart pointers that implement CoerceUnsized but have strange behavior. See the dedicated internals thread for more details -- also, please keep conversation on the thread, and not on the Github issue. ❤️
Kixunil, fogti, KisaragiEffective and stepancheg95th, burdges and SOF3
Metadata
Metadata
Assignees
Labels
C-bugCategory: This is a bug.Category: This is a bug.E-needs-mcveCall for participation: This issue has a repro, but needs a Minimal Complete and Verifiable ExampleCall for participation: This issue has a repro, but needs a Minimal Complete and Verifiable ExampleF-coerce_unsizedThe `CoerceUnsized` traitThe `CoerceUnsized` traitI-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/SoundnessP-mediumMedium priorityMedium priorityT-langRelevant to the language teamRelevant to the language teamrequires-nightlyThis issue requires a nightly compiler in some way.This issue requires a nightly compiler in some way.
Type
Projects
Milestone
Relationships
Development
Select code repository
Activity
Rollup merge of rust-lang#68004 - nikomatsakis:negative-impls, r=varkor
Rollup merge of rust-lang#68004 - nikomatsakis:negative-impls, r=varkor
nikomatsakis commentedon Jun 23, 2020
Lowering the priority of this to medium, adding as a blocker to #27732 (coerce unsized stabilization).
mzji commentedon Jul 4, 2020
steffahn commentedon May 9, 2021
Update: It is possible to abuse existing
CoerceUnsizedimplementations onstable. See #85099 (although I created that issue before reading any of this issue and its IRLO thread, so don’t expect any syntactic similarity to the unsoundness examples of this issue).The type
Pin<&LocalType>implementsDeref<Target = LocalType>but it doesn’t implementDerefMut. The typesPinand&are#[fundamental]so that animpl DerefMut for Pin<&LocalType>>is possible. You can useLocalType == SomeLocalStructorLocalType == dyn LocalTraitand you can coercePin<Pin<&SomeLocalStruct>>intoPin<Pin<&dyn LocalTrait>>. (Indeed, two layers ofPin!!) This allows creating a pair of “smart pointers that implementCoerceUnsizedbut have strange behavior” on stable (Pin<&SomeLocalStruct>andPin<&dyn LocalTrait>become the smart pointers with “strange behavior” and they already implementCoerceUnsized).More concretely: Since
Pin<&dyn LocalTrait>: Deref<dyn LocalTrait>, a “strange behavior”DerefMutimplementation ofPin<&dyn LocalTrait>can be used to dereference an underlyingPin<&SomeLocalStruct>into, effectively, a target type (wrapped in the trait object) that’s different fromSomeLocalStruct. The structSomeLocalStructmight always beUnpinwhile the different type behind the&mut dyn LocalTraitreturned byDerefMutcan be!Unpin. HavingSomeLocalStruct: Unpinallows for easy creation of thePin<Pin<&SomeLocalStruct>>which coerces intoPin<Pin<&dyn LocalTrait>>even thoughPin<&dyn LocalTrait>::Target: !Unpin(and even the actualTargettype inside of the trait object being returned by theDerefMutcan be!Unpin).Methods on
LocalTraitcan be used both to make theDerefMutimplementation possible and to convert thePin<&mut dyn LocalTrait>(from aPin::as_mutcall on&mut Pin<Pin<&dyn LocalTrait>>) back into a pinned mutable referene to the concrete “type behind the&mut dyn LocalTraitreturned byDerefMut”.Pinunsoundness involving animpl DerefMut for Pin<&dyn LocalTrait>#85099known-bugtests for all(?) I-unsound issues #105107Darksonn commentedon Aug 4, 2025
I just came across this. I believe this was solved by the addition of
PinCoerceUnsized. See also this section of thederive(SmartPointer)RFC.Pin::new’s check forTarget: Unpinbecomes insufficient #134407