| // 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`. |
| thread::spawn(move || { |
| //~^ ERROR borrowed data escapes outside of function |
| 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(); |
| } |