Skip to content

Instantly share code, notes, and snippets.

@tarcieri
Last active August 29, 2015 14:01
Show Gist options
  • Select an option

  • Save tarcieri/ec3ba55967eedf65c9cb to your computer and use it in GitHub Desktop.

Select an option

Save tarcieri/ec3ba55967eedf65c9cb to your computer and use it in GitHub Desktop.
Playing around with mmap()ed secret buffers in Rust
extern crate libc;
extern crate rand;
use std::os;
use std::cast::transmute;
use std::raw::Slice;
use std::intrinsics;
use libc::types::common::c95::c_void;
use libc::funcs::posix88::mman::{mmap, mlock, munmap};
use libc::consts::os::posix88::{PROT_READ, PROT_WRITE};
use libc::consts::os::posix88::{MAP_ANON, MAP_PRIVATE, MAP_FAILED};
use rand::{task_rng, Rng};
pub struct Secret {
len: uint,
ptr: *mut u8
}
impl Secret {
pub fn new(len: uint) -> Secret {
let ptr = unsafe {
let c_ptr = mmap(0 as *c_void, len as u64, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0) as *c_void;
if c_ptr == MAP_FAILED {
fail!("mmap() failed: {}", os::last_os_error());
}
if mlock(c_ptr, len as u64) != 0 {
fail!("mlock() failed: {}", os::last_os_error());
}
c_ptr as *mut u8
};
Secret { len: len, ptr: ptr }
}
pub fn as_mut_slice(&mut self) -> &mut [u8] {
unsafe { transmute(Slice { data: self.ptr as *u8, len: self.len }) }
}
}
impl Drop for Secret {
fn drop(&mut self) {
unsafe {
intrinsics::volatile_set_memory(self.ptr, 0u8, self.len);
munmap(self.ptr as *c_void, self.len as u64);
}
}
}
fn main() {
let mut secret = Secret::new(16);
println!("Secret: {:?}", secret);
println!("Zeroed bytes: {:?}", secret.as_mut_slice());
task_rng().fill_bytes(secret.as_mut_slice());
println!("Filled bytes: {:?}", secret.as_mut_slice());
}
@tarcieri

tarcieri commented May 7, 2014

Copy link
Copy Markdown
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment