// The Most Memory Safe Buffer Overflow in Rust! // // Consider all the code below under Public Domain // // How to build: // $ rustc main.rs // // Wrong password: // $ printf "hello\n" | ./main // // Right password: // $ printf "password\n" | ./main // // Universal password: // $ printf "aaaaaaaaaaaaaa\0aaaaaaaaaaaaaa\0" | ./main // // Support Rust Recovery Foundation: https://rustrecoveryfoundation.neocities.org/ use std::io::{BufRead, Write}; const BUF_CAP: usize = 15; type Ptr = usize; fn alloc_buffer(mem: &mut Vec::, size: usize) -> Ptr { let result = mem.len(); for _ in 0..size { mem.push(' ') } result } fn alloc_str(mem: &mut Vec, s: &str) -> Ptr { let result = mem.len(); for c in s.chars() { mem.push(c) } mem.push('\0'); result } fn read_line_into_buffer(input: &mut impl BufRead, mem: &mut Vec, buf: Ptr) { let mut s = String::new(); let n = input.read_line(&mut s).unwrap(); for (i, c) in s.chars().enumerate() { mem[buf + i] = c; } if mem[buf + n - 1] == '\n' { mem[buf + n - 1] = '\0' } else { mem[buf + n] = '\0'; } } fn streq(mem: &Vec, mut s1: Ptr, mut s2: Ptr) -> bool { while mem[s1] != '\0' && mem[s2] != '\0' { if mem[s1] != mem[s2] { return false; } s1 += 1; s2 += 1; } mem[s1] == '\0' && mem[s2] == '\0' } fn main() { let mut mem = Vec::::new(); let buffer = alloc_buffer(&mut mem, BUF_CAP); let password = alloc_str(&mut mem, "password"); alloc_buffer(&mut mem, BUF_CAP); print!("Password: "); std::io::stdout().flush().unwrap(); read_line_into_buffer(&mut std::io::stdin().lock(), &mut mem, buffer); if streq(&mem, buffer, password) { println!("Access Granted!") } else { println!("Access Denied!") } }