35 lines
923 B
Rust
35 lines
923 B
Rust
// Regression test for 132104
|
|
|
|
#![feature(coroutine_trait, coroutines)]
|
|
|
|
use std::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);
|
|
}
|
|
});
|
|
|
|
// exploit:
|
|
generator.as_mut().resume("");
|
|
generator.as_mut().resume(s); // <- generator hoards it as `let ctx`.
|
|
//~^ ERROR borrowed data escapes outside of function
|
|
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();
|
|
}
|