1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
//! Domain expansion: `'static` lifetime
//!
//! This is the cursed witchery behind all the bugs we have implemented so far.
//!
//! # How it works
//!
//! There is a soundness hole in the Rust compiler that allows our domain expansion to work.
//!
//! In the [`expand`] function, we use [`lifetime_translator`] with [`STATIC_UNIT`],
//! which has a `'static` lifetime, allowing us to translate an arbitrary lifetime
//! into any other lifetime.
//!
//! `rustc` *should* infer that one of the lifetimes does not outlive `'static`, so
//! that we can't use [`lifetime_translator`]; however, for whatever reason, it doesn't,
//! so this exploit works.
//!
//! See <https://github.com/rust-lang/rust/issues/25860> for this bug's bug report.
//! It's been open for multiple years!
/// Converts lifetime `'b` to lifetime `'a`.
///
/// This function, on its own, is sound:
/// - `_val_a`'s lifetime is `&'a &'b`. This means that `'b` must outlive `'a`, so
/// that the `'a` reference is never dangling. If `'a` outlived `'b` then it could
/// borrow data that's already been dropped.
/// - Therefore, `val_b`, which has a lifetime of `'b`, is valid for `'a`.
pub const Sized>
/// This does the same thing as [`lifetime_translator`], just for mutable refs.
Sized>
/// Expands the domain of `'a` to `'b`.
///
/// # Safety
///
/// Safety? What's that?
Sized>
/// This does the same thing as [`expand`] for mutable references.
///
/// # Safety
///
/// Safety? What's that?
Sized>
/// A unit with a static lifetime.
///
/// Thanks to the soundness hole, this lets us cast any value all the way up to
/// a `'static` lifetime, meaning any lifetime we want.
pub const STATIC_UNIT: && = &&;