Initialize a randon number on stack for the stack protector

This commit is contained in:
LI Qing 2020-12-10 14:17:46 +08:00 committed by Zongmin.Gu
parent 0c5843492b
commit 40a52b56be
6 changed files with 51 additions and 22 deletions

@ -1,21 +1,14 @@
use super::*; use super::*;
use crate::net::PollEventFlags; use crate::net::PollEventFlags;
use crate::util::random;
#[derive(Debug)] #[derive(Debug)]
pub struct DevRandom; pub struct DevRandom;
extern "C" {
fn sgx_read_rand(rand_buf: *mut u8, buf_size: usize) -> sgx_status_t;
}
impl File for DevRandom { impl File for DevRandom {
fn read(&self, _buf: &mut [u8]) -> Result<usize> { fn read(&self, _buf: &mut [u8]) -> Result<usize> {
let (buf, size) = _buf.as_mut().as_mut_ptr_and_len(); random::get_random(_buf)?;
let status = unsafe { sgx_read_rand(buf, size) }; Ok(_buf.len())
if status != sgx_status_t::SGX_SUCCESS {
return_errno!(EAGAIN, "failed to get random number from sgx");
}
Ok(size)
} }
fn read_at(&self, _offset: usize, _buf: &mut [u8]) -> Result<usize> { fn read_at(&self, _offset: usize, _buf: &mut [u8]) -> Result<usize> {

@ -1,20 +1,13 @@
use super::*; use super::*;
use crate::util::random;
use rcore_fs_sefs::dev::{SefsUuid, UuidProvider}; use rcore_fs_sefs::dev::{SefsUuid, UuidProvider};
use sgx_types::sgx_status_t;
extern "C" {
fn sgx_read_rand(rand_buf: *mut u8, buf_size: usize) -> sgx_status_t;
}
pub struct SgxUuidProvider; pub struct SgxUuidProvider;
impl UuidProvider for SgxUuidProvider { impl UuidProvider for SgxUuidProvider {
fn generate_uuid(&self) -> SefsUuid { fn generate_uuid(&self) -> SefsUuid {
let mut uuid: [u8; 16] = [0u8; 16]; let mut uuid: [u8; 16] = [0u8; 16];
let buf = uuid.as_mut_ptr(); random::get_random(&mut uuid).expect("failed to get random number");
let size = 16;
let status = unsafe { sgx_read_rand(buf, size) };
assert!(status == sgx_status_t::SGX_SUCCESS);
SefsUuid(uuid) SefsUuid(uuid)
} }
} }

@ -4,6 +4,7 @@ use std::{mem, ptr};
use super::aux_vec::{AuxKey, AuxVec}; use super::aux_vec::{AuxKey, AuxVec};
use crate::prelude::*; use crate::prelude::*;
use crate::util::random;
/* /*
* The initial stack of a process looks like below: * The initial stack of a process looks like below:
@ -53,11 +54,13 @@ pub fn do_init(
init_area_size: usize, init_area_size: usize,
argv: &[CString], argv: &[CString],
envp: &[CString], envp: &[CString],
auxtbl: &AuxVec, auxtbl: &mut AuxVec,
) -> Result<usize> { ) -> Result<usize> {
let stack_buf = unsafe { StackBuf::new(stack_top, init_area_size)? }; let stack_buf = unsafe { StackBuf::new(stack_top, init_area_size)? };
let envp_cloned = clone_cstrings_on_stack(&stack_buf, envp)?; let envp_cloned = clone_cstrings_on_stack(&stack_buf, envp)?;
let argv_cloned = clone_cstrings_on_stack(&stack_buf, argv)?; let argv_cloned = clone_cstrings_on_stack(&stack_buf, argv)?;
let rand_val_ptr = generate_random_on_stack(&stack_buf)?;
auxtbl.set(AuxKey::AT_RANDOM, rand_val_ptr as *const () as u64);
adjust_alignment(&stack_buf, auxtbl, &envp_cloned, &argv_cloned)?; adjust_alignment(&stack_buf, auxtbl, &envp_cloned, &argv_cloned)?;
dump_auxtbl_on_stack(&stack_buf, auxtbl)?; dump_auxtbl_on_stack(&stack_buf, auxtbl)?;
dump_cstrptrs_on_stack(&stack_buf, &envp_cloned)?; dump_cstrptrs_on_stack(&stack_buf, &envp_cloned)?;
@ -146,6 +149,15 @@ impl StackBuf {
} }
} }
fn generate_random_on_stack(stack: &StackBuf) -> Result<*const u8> {
let rand_val = {
let mut rand: [u8; 16] = [0; 16];
random::get_random(&mut rand)?;
rand
};
stack.put_slice(&rand_val)
}
fn clone_cstrings_on_stack<'a, 'b>( fn clone_cstrings_on_stack<'a, 'b>(
stack: &'a StackBuf, stack: &'a StackBuf,
cstrings: &'b [CString], cstrings: &'b [CString],

@ -130,7 +130,7 @@ fn new_process(
let process_ref = current_ref.process().clone(); let process_ref = current_ref.process().clone();
let vm = init_vm::do_init(&exec_elf_file, &ldso_elf_file)?; let vm = init_vm::do_init(&exec_elf_file, &ldso_elf_file)?;
let auxvec = init_auxvec(&vm, &exec_elf_file)?; let mut auxvec = init_auxvec(&vm, &exec_elf_file)?;
// Notify debugger to load the symbols from elf file // Notify debugger to load the symbols from elf file
let ldso_elf_base = vm.get_elf_ranges()[1].start() as u64; let ldso_elf_base = vm.get_elf_ranges()[1].start() as u64;
@ -162,7 +162,7 @@ fn new_process(
}; };
let user_stack_base = vm.get_stack_base(); let user_stack_base = vm.get_stack_base();
let user_stack_limit = vm.get_stack_limit(); let user_stack_limit = vm.get_stack_limit();
let user_rsp = init_stack::do_init(user_stack_base, 4096, &argv, envp, &auxvec)?; let user_rsp = init_stack::do_init(user_stack_base, 4096, &argv, envp, &mut auxvec)?;
unsafe { unsafe {
Task::new( Task::new(
ldso_entry, ldso_entry,

@ -4,5 +4,6 @@ pub mod dirty;
pub mod log; pub mod log;
pub mod mem_util; pub mod mem_util;
pub mod mpx_util; pub mod mpx_util;
pub mod random;
pub mod sgx; pub mod sgx;
pub mod sync; pub mod sync;

@ -0,0 +1,30 @@
use super::*;
use sgx_types::sgx_status_t;
const MAX_RETRIES: u32 = 50;
pub fn get_random(rand: &mut [u8]) -> Result<()> {
extern "C" {
fn sgx_read_rand(rand_buf: *mut u8, buf_size: usize) -> sgx_status_t;
}
if rand.is_empty() {
return Ok(());
}
// sgx_read_rand() may fail because of HW failure of RDRAND instruction,
// add retries to get the random number.
for _ in 0..MAX_RETRIES {
let status = unsafe { sgx_read_rand(rand.as_mut_ptr(), rand.len()) };
match status {
sgx_status_t::SGX_SUCCESS => {
return Ok(());
}
sgx_status_t::SGX_ERROR_INVALID_PARAMETER => {
panic!("invalid argument to get random number from SGX");
}
_ => {}
}
}
Err(errno!(EAGAIN, "failed to get random number from SGX"))
}