cve-rs 0.7.0

Blazingly fast memory vulnerabilities, written in 100% safe Rust.
Documentation
//! Behold, a perfectly memory-safe use-after-free!

use std::hint::black_box;
use std::io::{stdin, stdout, Read, Write};

use crate::lifetime_expansion;

/// The size of the buffer we create and then drop.
const HORRIBLE_LEN: usize = 64;

/// Get a static reference to a dropped buffer.
#[inline(never)]
fn get_horrible_buffer_mut() -> &'static mut [u8; HORRIBLE_LEN] {
	let mut buffer = black_box([0; HORRIBLE_LEN]);
	lifetime_expansion::expand_mut(&mut buffer)
}

#[inline(never)]
fn innocent_prompt() {
	print!("Give text (must be at least {HORRIBLE_LEN} chars) > ");
	stdout().flush().unwrap();
}

/// Reads data from a freed buffer, puts random data on the stack, then reads it again.
#[inline(never)]
fn innocent_read(initial_buffer_mut: &mut [u8; HORRIBLE_LEN]) {
	let mut stdin = black_box(stdin());

	println!("Buffer before writing:\n{initial_buffer_mut:?}");

	let _buffer = black_box([0_u8; HORRIBLE_LEN / 2]);
	let _thing = black_box(69_727_420_u64);

	println!("Buffer after creating random data:\n{initial_buffer_mut:?}");

	innocent_prompt();

	// "Nah, I'd win." - Rust compiler
	stdin.read_exact(initial_buffer_mut).unwrap();

	println!("Buffer after writing user input:\n{initial_buffer_mut:?}");
}

/// Create a buffer and drop it, then read from it in `innocent_read`.
pub fn use_after_free() {
	let initial_buffer_mut = get_horrible_buffer_mut();
	innocent_read(initial_buffer_mut);
}