Description
openedon Jan 22, 2024
This particular exploitation is possible since #113262. I’m not certain if there wasn’t any way to convince the compiler to do such casts before that; if there wasn’t, then that PR was definitely a lot more than “a bugfix”.
Edit: Turns out, there is a way, see my first answer below. (Does this mean the regression label should be removed, since the regression only extended the scope of the issue a bit? So this becomes an issue for F-arbitrary_self_types
in general then? Should we also add requires-nightly
label?)
So apparently, the compiler doesn’t care about lifetimes for trait object metadata when checking casts between pointers. This means I can coerce *const dyn Foo<'a>
into *const dyn Foo<'b>
without restrictions. Since vtables logically contain function pointers, like for example a vtable for trait Foo<'a> { fn foo(&self) -> &'a str }
logically contains something like unsafe fn(*const ()) -> &'a str
this results in casting the types of these function pointers.
Now one could argue “it’s fine, they are raw pointers, you can’t do anything with *const dyn NotQuiteTheRightTrait
”, but as far as I’m aware, the story on that is that you can, vtables must be valid (at least as a soundness invariant, not necessarily promising instant UB), and we should not break arbitrary_self_types
’s soundness this way, for now.
And with arbitrary_self_types
, unsoundness there is!
#![feature(arbitrary_self_types)]
trait Static<'a> {
fn proof(self: *const Self, s: &'a str) -> &'static str;
}
fn bad_cast<'a>(x: *const dyn Static<'static>) -> *const dyn Static<'a> {
x as _
}
impl Static<'static> for () {
fn proof(self: *const Self, s: &'static str) -> &'static str {
s
}
}
fn extend_lifetime(s: &str) -> &'static str {
bad_cast(&()).proof(s)
}
fn main() {
let s = String::from("Hello World");
let slice = extend_lifetime(&s);
println!("Now it exists: {slice}");
drop(s);
println!("Now it’s gone: {slice}");
}
Now it exists: Hello World
Now it’s gone: �@7
@rustbot label +I-unsound +F-arbitrary_self_types +A-lifetimes +A-coercions +A-trait-objects +requires-nightly