-
-
Notifications
You must be signed in to change notification settings - Fork 14.7k
Rust allows impl Fn(T<'a>) -> T<'b> to be : 'static, which is unsound #112905
Copy link
Copy link
Open
Labels
A-impl-traitArea: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch.Area: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch.A-varianceArea: Variance (https://doc.rust-lang.org/nomicon/subtyping.html)Area: Variance (https://doc.rust-lang.org/nomicon/subtyping.html)C-bugCategory: This is a bug.Category: This is a bug.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/SoundnessP-highHigh priorityHigh priorityS-bug-has-testStatus: This bug is tracked inside the repo by a `known-bug` test.Status: This bug is tracked inside the repo by a `known-bug` test.T-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.regression-from-stable-to-stablePerformance or correctness regression from one stable version to another.Performance or correctness regression from one stable version to another.
Metadata
Metadata
Assignees
Labels
A-impl-traitArea: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch.Area: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch.A-varianceArea: Variance (https://doc.rust-lang.org/nomicon/subtyping.html)Area: Variance (https://doc.rust-lang.org/nomicon/subtyping.html)C-bugCategory: This is a bug.Category: This is a bug.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/SoundnessP-highHigh priorityHigh priorityS-bug-has-testStatus: This bug is tracked inside the repo by a `known-bug` test.Status: This bug is tracked inside the repo by a `known-bug` test.T-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.regression-from-stable-to-stablePerformance or correctness regression from one stable version to another.Performance or correctness regression from one stable version to another.
Type
Fields
Give feedbackNo fields configured for issues without a type.
Projects
Status
open/unblocked
This is similar to #84366, but I don't know if I would say it's exactly the same. For instance, the exploit involves no associated types (no
OutputofFnOnceat all), just the mere approach of:type F<'a, 'b> = impl Fn(T<'a>) -> T<'b> : 'static;dyn Any-erase it.F<'c, 'd>(e.g.,'a = 'b = 'c, and'd = 'whatever_you_want).Mainly, the
-> T<'b>return could always become an&mut Option<T<'b>>out parameter (so as to have a-> ()returning closure), so the return type of the closure not being: 'staticis not really the issue; it's really about the closure being allowed to be: 'staticdespite any part of the closure API being non-'static.In fact, before
1.66.0, we did haveimpl 'static + Fn(&'a ())being'a-infected (and thus non: 'static). While a very surprising property, it seems to be a more sound one that what we currently have.The simplest possible exploit, with no
unsafe(-but-sound) helper API (replaced by an implicit bound trick) requires:T<'lt>to be covariant;type_alias_impl_trait.I'll start with that snippet nonetheless to get people familiarized with the context:
Now, to avoid blaming implicit bounds and/or
type_alias_impl_trait, here is a snippet not using either (which thus works independently of variance or lack thereof).It does require
unsafeto offer a sound API (it's the "witness types" / "witness lifetimes" pattern, wherein you can be dealing with a generic API with two potentially distinct generic parameters, but you have an instance ofEqWitness<T, U>orEqWitness<'a, 'b>, with such instances only being constructible for<T, T>or<'a, 'a>.With this tool/library at our disposal, we can then exploit it:
This happens since
1.66.0.@rustbot modify labels: +I-unsound +regression-from-stable-to-stable