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

@ -1,20 +1,13 @@
use super::*;
use crate::util::random;
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;
impl UuidProvider for SgxUuidProvider {
fn generate_uuid(&self) -> SefsUuid {
let mut uuid: [u8; 16] = [0u8; 16];
let buf = uuid.as_mut_ptr();
let size = 16;
let status = unsafe { sgx_read_rand(buf, size) };
assert!(status == sgx_status_t::SGX_SUCCESS);
random::get_random(&mut uuid).expect("failed to get random number");
SefsUuid(uuid)
}
}

@ -4,6 +4,7 @@ use std::{mem, ptr};
use super::aux_vec::{AuxKey, AuxVec};
use crate::prelude::*;
use crate::util::random;
/*
* The initial stack of a process looks like below:
@ -53,11 +54,13 @@ pub fn do_init(
init_area_size: usize,
argv: &[CString],
envp: &[CString],
auxtbl: &AuxVec,
auxtbl: &mut AuxVec,
) -> Result<usize> {
let stack_buf = unsafe { StackBuf::new(stack_top, init_area_size)? };
let envp_cloned = clone_cstrings_on_stack(&stack_buf, envp)?;
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)?;
dump_auxtbl_on_stack(&stack_buf, auxtbl)?;
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>(
stack: &'a StackBuf,
cstrings: &'b [CString],

@ -130,7 +130,7 @@ fn new_process(
let process_ref = current_ref.process().clone();
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
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_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 {
Task::new(
ldso_entry,

@ -4,5 +4,6 @@ pub mod dirty;
pub mod log;
pub mod mem_util;
pub mod mpx_util;
pub mod random;
pub mod sgx;
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"))
}