I tried this code:
#![forbid(unsafe_code)]
#![feature(coroutine_trait, coroutines)]
use ::core::ops::Coroutine;
use ::std::{thread, time};
fn demo<'not_static>(s: &'not_static str) -> thread::JoinHandle<()> {
let mut generator = Box::pin({
#[coroutine]
move |_ctx| {
let ctx: &'not_static str = yield;
yield;
dbg!(ctx);
}
});
// PROBLEM: `typeof(generator) : 'static`!
let _assert_usable_for_static: &dyn ::core::any::Any = &generator;
// exploit:
generator.as_mut().resume("");
generator.as_mut().resume(s); // <- generator hoards it as `let ctx`.
thread::spawn(move || {
thread::sleep(time::Duration::from_millis(200));
generator.as_mut().resume(""); // <- resumes from the last `yield`, running `dbg!(ctx)`.
})
}
fn main() {
let local = String::from("...");
let thread = demo(&local);
drop(local);
let _unrelated = String::from("UAF");
thread.join().unwrap();
}
I expected to see this happen:
Compilation error because 'not_static : 'static would be needed for that spawn() (or Any) to pass.
Instead, this happened:
No compilation error, thus unsoundness ensues (coroutine prints UAF in the current playground, thereby proving it is reading unrelated/UAF memory. Miri reports UB).
Meta
@rustbot label +I-unsound +A-coroutines +F-coroutines +F-coroutine_trait +requires-nightly
I tried this code:
I expected to see this happen:
Compilation error because
'not_static : 'staticwould be needed for thatspawn()(orAny) to pass.Instead, this happened:
No compilation error, thus unsoundness ensues (coroutine prints
UAFin the current playground, thereby proving it is reading unrelated/UAF memory. Miri reports UB).Meta
rustc --version --verbose:@rustbot label +I-unsound +A-coroutines +F-coroutines +F-coroutine_trait +requires-nightly