diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/ui/coroutine/resume-arg-outlives-2.rs | 34 | ||||
| -rw-r--r-- | tests/ui/coroutine/resume-arg-outlives-2.stderr | 17 | ||||
| -rw-r--r-- | tests/ui/coroutine/resume-arg-outlives.rs | 27 | ||||
| -rw-r--r-- | tests/ui/coroutine/resume-arg-outlives.stderr | 20 |
4 files changed, 98 insertions, 0 deletions
diff --git a/tests/ui/coroutine/resume-arg-outlives-2.rs b/tests/ui/coroutine/resume-arg-outlives-2.rs new file mode 100644 index 00000000000..387b143ea27 --- /dev/null +++ b/tests/ui/coroutine/resume-arg-outlives-2.rs @@ -0,0 +1,34 @@ +// 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(); +} diff --git a/tests/ui/coroutine/resume-arg-outlives-2.stderr b/tests/ui/coroutine/resume-arg-outlives-2.stderr new file mode 100644 index 00000000000..3d630d7e7e4 --- /dev/null +++ b/tests/ui/coroutine/resume-arg-outlives-2.stderr @@ -0,0 +1,17 @@ +error[E0521]: borrowed data escapes outside of function + --> $DIR/resume-arg-outlives-2.rs:20:5 + | +LL | fn demo<'not_static>(s: &'not_static str) -> thread::JoinHandle<()> { + | ----------- - `s` is a reference that is only valid in the function body + | | + | lifetime `'not_static` defined here +... +LL | generator.as_mut().resume(s); // <- generator hoards it as `let ctx`. + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | `s` escapes the function body here + | argument requires that `'not_static` must outlive `'static` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0521`. diff --git a/tests/ui/coroutine/resume-arg-outlives.rs b/tests/ui/coroutine/resume-arg-outlives.rs new file mode 100644 index 00000000000..258be28e063 --- /dev/null +++ b/tests/ui/coroutine/resume-arg-outlives.rs @@ -0,0 +1,27 @@ +// Regression test for 132104 + +#![feature(coroutine_trait, coroutines)] + +use std::ops::Coroutine; +use std::pin::Pin; + +fn demo<'not_static>(s: &'not_static str) -> Pin<Box<impl Coroutine<&'not_static str> + 'static>> { + let mut generator = Box::pin({ + #[coroutine] + move |ctx: &'not_static str| { + yield; + dbg!(ctx); + } + }); + generator.as_mut().resume(s); + generator + //~^ ERROR lifetime may not live long enough +} + +fn main() { + let local = String::from("..."); + let mut coro = demo(&local); + drop(local); + let _unrelated = String::from("UAF"); + coro.as_mut().resume(""); +} diff --git a/tests/ui/coroutine/resume-arg-outlives.stderr b/tests/ui/coroutine/resume-arg-outlives.stderr new file mode 100644 index 00000000000..2a6337b4945 --- /dev/null +++ b/tests/ui/coroutine/resume-arg-outlives.stderr @@ -0,0 +1,20 @@ +error: lifetime may not live long enough + --> $DIR/resume-arg-outlives.rs:17:5 + | +LL | fn demo<'not_static>(s: &'not_static str) -> Pin<Box<impl Coroutine<&'not_static str> + 'static>> { + | ----------- lifetime `'not_static` defined here +... +LL | generator + | ^^^^^^^^^ returning this value requires that `'not_static` must outlive `'static` + | +help: consider changing `impl Coroutine<&'not_static str> + 'static`'s explicit `'static` bound to the lifetime of argument `s` + | +LL | fn demo<'not_static>(s: &'not_static str) -> Pin<Box<impl Coroutine<&'not_static str> + 'not_static>> { + | ~~~~~~~~~~~ +help: alternatively, add an explicit `'static` bound to this reference + | +LL | fn demo<'not_static>(s: &'static str) -> Pin<Box<impl Coroutine<&'not_static str> + 'static>> { + | ~~~~~~~~~~~~ + +error: aborting due to 1 previous error + |
