Support page fault
This commit is contained in:
parent
3939899e76
commit
655869711a
89
deps/rust-sgx-sdk.patch
vendored
89
deps/rust-sgx-sdk.patch
vendored
@ -1,3 +1,17 @@
|
||||
From ba4147e76c7cfe17f843b7b28bf535d04bc5db77 Mon Sep 17 00:00:00 2001
|
||||
From: "Tate, Hongliang Tian" <tate.thl@antfin.com>
|
||||
Date: Wed, 3 Jun 2020 08:11:35 +0000
|
||||
Subject: [PATCH 1/3] Add support for integrity-only SGX files
|
||||
|
||||
---
|
||||
samplecode/unit-test/enclave/src/lib.rs | 2 +
|
||||
samplecode/unit-test/enclave/src/test_file.rs | 41 +++++++++
|
||||
sgx_tprotected_fs/src/fs.rs | 84 +++++++++++++++++++
|
||||
sgx_tstd/src/sgxfs.rs | 39 ++++++++-
|
||||
sgx_tstd/src/sys/sgxfs.rs | 38 +++++++--
|
||||
sgx_types/src/function.rs | 6 +-
|
||||
6 files changed, 203 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/samplecode/unit-test/enclave/src/lib.rs b/samplecode/unit-test/enclave/src/lib.rs
|
||||
index b9ea49be..d740753f 100644
|
||||
--- a/samplecode/unit-test/enclave/src/lib.rs
|
||||
@ -356,3 +370,78 @@ index 3c2db3a4..f96cd9e8 100644
|
||||
}
|
||||
|
||||
/* intel sgx sdk 2.0 */
|
||||
--
|
||||
2.17.1
|
||||
|
||||
|
||||
From 982897c432dd98c6d63691ddb238acd29db4233f Mon Sep 17 00:00:00 2001
|
||||
From: "Tate, Hongliang Tian" <tate.thl@antfin.com>
|
||||
Date: Wed, 3 Jun 2020 08:35:53 +0000
|
||||
Subject: [PATCH 2/3] Add data structures for #PF and #GP exceptions
|
||||
|
||||
---
|
||||
sgx_types/src/types.rs | 11 +++++++++++
|
||||
1 file changed, 11 insertions(+)
|
||||
|
||||
diff --git a/sgx_types/src/types.rs b/sgx_types/src/types.rs
|
||||
index 4f191364..651d088e 100644
|
||||
--- a/sgx_types/src/types.rs
|
||||
+++ b/sgx_types/src/types.rs
|
||||
@@ -865,6 +865,8 @@ impl_enum! {
|
||||
SGX_EXCEPTION_VECTOR_BP = 3, /* INT 3 instruction */
|
||||
SGX_EXCEPTION_VECTOR_BR = 5, /* BOUND instruction */
|
||||
SGX_EXCEPTION_VECTOR_UD = 6, /* UD2 instruction or reserved opcode */
|
||||
+ SGX_EXCEPTION_VECTOR_GP = 13, /* General protection */
|
||||
+ SGX_EXCEPTION_VECTOR_PF = 14, /* Page fault */
|
||||
SGX_EXCEPTION_VECTOR_MF = 16, /* x87 FPU floating-point or WAIT/FWAIT instruction */
|
||||
SGX_EXCEPTION_VECTOR_AC = 17, /* Any data reference in memory */
|
||||
SGX_EXCEPTION_VECTOR_XM = 19, /* SSE/SSE2/SSE3 floating-point instruction */
|
||||
@@ -922,11 +924,20 @@ cfg_if! {
|
||||
}
|
||||
}
|
||||
|
||||
+impl_struct! {
|
||||
+ pub struct sgx_exinfo_t {
|
||||
+ pub maddr: u64,
|
||||
+ pub errcd: u32,
|
||||
+ pub _unused: u32,
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
impl_struct! {
|
||||
pub struct sgx_exception_info_t {
|
||||
pub cpu_context: sgx_cpu_context_t,
|
||||
pub exception_vector: sgx_exception_vector_t,
|
||||
pub exception_type: sgx_exception_type_t,
|
||||
+ pub exinfo: sgx_exinfo_t,
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
2.17.1
|
||||
|
||||
|
||||
From 43b32d82c09a796fd52b954dc0217ac9ce01c559 Mon Sep 17 00:00:00 2001
|
||||
From: "Tate, Hongliang Tian" <tate.thl@antfin.com>
|
||||
Date: Wed, 3 Jun 2020 08:37:47 +0000
|
||||
Subject: [PATCH 3/3] Add a new exception type: simulated
|
||||
|
||||
---
|
||||
sgx_types/src/types.rs | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/sgx_types/src/types.rs b/sgx_types/src/types.rs
|
||||
index 651d088e..ef43d7d6 100644
|
||||
--- a/sgx_types/src/types.rs
|
||||
+++ b/sgx_types/src/types.rs
|
||||
@@ -879,6 +879,7 @@ impl_enum!{
|
||||
pub enum sgx_exception_type_t {
|
||||
SGX_EXCEPTION_HARDWARE = 3,
|
||||
SGX_EXCEPTION_SOFTWARE = 6,
|
||||
+ SGX_EXCEPTION_SIMULATED = 7,
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
2.17.1
|
||||
|
||||
|
@ -24,10 +24,11 @@ serde_json = { path = "../../deps/serde-json-sgx" }
|
||||
sgx_tstd = { path = "../../deps/rust-sgx-sdk/sgx_tstd" }
|
||||
|
||||
[features]
|
||||
default = ["integrity_only_opt", "sgx_file_cache"]
|
||||
default = ["integrity_only_opt", "sgx_file_cache", "sgx1_exception_sim"]
|
||||
syscall_timing = [] # Timing for each syscall. But it has cost from more ocall.
|
||||
integrity_only_opt = [] # Clear bss only. It should be disabled if checking memory reads.
|
||||
sgx_file_cache = [] # Cache SgxFile objects. Invalidation is unimplemented.
|
||||
sgx1_exception_sim = [] # Simulate #PF and #GP exceptions on SGX 1
|
||||
|
||||
[target.'cfg(not(target_env = "sgx"))'.dependencies]
|
||||
xmas-elf = { path = "../../deps/xmas-elf" }
|
||||
|
@ -37,9 +37,7 @@ pub fn do_handle_exception(
|
||||
user_context: *mut CpuContext,
|
||||
) -> Result<isize> {
|
||||
let info = unsafe { &mut *info };
|
||||
if info.exception_type != sgx_exception_type_t::SGX_EXCEPTION_HARDWARE {
|
||||
return_errno!(EINVAL, "Can only handle hardware exceptions");
|
||||
}
|
||||
check_exception_type(info.exception_type)?;
|
||||
|
||||
let user_context = unsafe { &mut *user_context };
|
||||
*user_context = CpuContext::from_sgx(&info.cpu_context);
|
||||
@ -72,3 +70,32 @@ pub fn do_handle_exception(
|
||||
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
// Notes about #PF and #GP exception simulation for SGX 1.
|
||||
//
|
||||
// SGX 1 cannot capture #PF and #GP exceptions inside enclaves. This leaves us
|
||||
// no choice but to rely on untrusted info about #PF or #PG exceptions from
|
||||
// outside the enclave. Due to the obvious security risk, the feature can be
|
||||
// disabled.
|
||||
//
|
||||
// On the bright side, SGX 2 has native support for #PF and #GP exceptions. So
|
||||
// this exception simulation and its security risk is not a problem in the long
|
||||
// run.
|
||||
|
||||
#[cfg(not(feature = "sgx1_exception_sim"))]
|
||||
fn check_exception_type(type_: sgx_exception_type_t) -> Result<()> {
|
||||
if type_ != sgx_exception_type_t::SGX_EXCEPTION_HARDWARE {
|
||||
return_errno!(EINVAL, "Can only handle hardware exceptions");
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(feature = "sgx1_exception_sim")]
|
||||
fn check_exception_type(type_: sgx_exception_type_t) -> Result<()> {
|
||||
if type_ != sgx_exception_type_t::SGX_EXCEPTION_HARDWARE
|
||||
&& type_ != sgx_exception_type_t::SGX_EXCEPTION_SIMULATED
|
||||
{
|
||||
return_errno!(EINVAL, "Can only handle hardware / simulated exceptions");
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -7,33 +7,52 @@ use crate::prelude::*;
|
||||
pub struct FaultSignal {
|
||||
num: SigNum,
|
||||
code: i32,
|
||||
addr: Option<u64>,
|
||||
}
|
||||
|
||||
impl FaultSignal {
|
||||
pub fn new(info: &sgx_exception_info_t) -> Self {
|
||||
// FIXME: the following mapping from exception to signal is not accurate.
|
||||
// TODO: the current mapping from exceptinon to signal is only a first
|
||||
// order approximation. The resulting signum or siginfo may not be
|
||||
// idential to Linux's behavior.
|
||||
use sgx_exception_vector_t::*;
|
||||
let (num, code) = match info.exception_vector {
|
||||
let (num, code, addr) = match info.exception_vector {
|
||||
// Divider exception
|
||||
SGX_EXCEPTION_VECTOR_DE => (SIGFPE, FPE_INTDIV),
|
||||
SGX_EXCEPTION_VECTOR_DE => (SIGFPE, FPE_INTDIV, None),
|
||||
// Floating-point exception
|
||||
SGX_EXCEPTION_VECTOR_MF |
|
||||
// SIMD floating-point exception
|
||||
SGX_EXCEPTION_VECTOR_XM => (SIGFPE, FPE_FLTDIV),
|
||||
SGX_EXCEPTION_VECTOR_XM => (SIGFPE, FPE_FLTDIV, None),
|
||||
// Invalid opcode exception
|
||||
SGX_EXCEPTION_VECTOR_UD |
|
||||
// Debug exception: should not occur in enclave; treat is as #UD
|
||||
SGX_EXCEPTION_VECTOR_DB |
|
||||
// Break point exception: should not occur in enclave; treat is as #UD
|
||||
SGX_EXCEPTION_VECTOR_BP => (SIGILL, ILL_ILLOPC),
|
||||
SGX_EXCEPTION_VECTOR_BP => (SIGILL, ILL_ILLOPC, None),
|
||||
// Bound range exception
|
||||
SGX_EXCEPTION_VECTOR_BR => (SIGSEGV, SEGV_BNDERR),
|
||||
SGX_EXCEPTION_VECTOR_BR => (SIGSEGV, SEGV_BNDERR, None),
|
||||
// Alignment check exception
|
||||
SGX_EXCEPTION_VECTOR_AC => (SIGBUS, BUS_ADRALN),
|
||||
// TODO: handle page fault and general protection exceptions
|
||||
_ => panic!("illegal exception: cannot be converted to signal"),
|
||||
SGX_EXCEPTION_VECTOR_AC => (SIGBUS, BUS_ADRALN, None),
|
||||
// Page fault exception
|
||||
SGX_EXCEPTION_VECTOR_PF => {
|
||||
const PF_ERR_FLAG_PRESENT : u32 = 1u32 << 0;
|
||||
let code = if info.exinfo.errcd & PF_ERR_FLAG_PRESENT != 0 {
|
||||
SEGV_ACCERR
|
||||
} else {
|
||||
SEGV_MAPERR
|
||||
};
|
||||
Self { num, code }
|
||||
let addr = Some(info.exinfo.maddr);
|
||||
(SIGSEGV, code, addr)
|
||||
},
|
||||
// General protection exception
|
||||
SGX_EXCEPTION_VECTOR_PF => (SIGBUS, BUS_ADRERR, None),
|
||||
_ => panic!("exception cannot be converted to signal"),
|
||||
};
|
||||
Self { num, code, addr }
|
||||
}
|
||||
|
||||
pub fn addr(&self) -> Option<u64> {
|
||||
self.addr
|
||||
}
|
||||
}
|
||||
|
||||
@ -43,8 +62,8 @@ impl Signal for FaultSignal {
|
||||
}
|
||||
|
||||
fn to_info(&self) -> siginfo_t {
|
||||
let info = siginfo_t::new(self.num, self.code);
|
||||
// TODO: set info.si_addr
|
||||
let mut info = siginfo_t::new(self.num, self.code);
|
||||
info.set_si_addr(self.addr.unwrap_or_default() as *const c_void);
|
||||
info
|
||||
}
|
||||
}
|
||||
|
@ -228,7 +228,7 @@ int div_maybe_zero(int x, int y) {
|
||||
return x / y;
|
||||
}
|
||||
|
||||
int test_catch_fault() {
|
||||
int test_handle_sigfpe() {
|
||||
#ifdef SGX_MODE_SIM
|
||||
printf("WARNING: Skip this test case as we do not support "
|
||||
"capturing hardware exception in SGX simulation mode\n");
|
||||
@ -261,6 +261,56 @@ int test_catch_fault() {
|
||||
#endif /* SGX_MODE_SIM */
|
||||
}
|
||||
|
||||
|
||||
// TODO: rewrite this in assembly
|
||||
int read_maybe_null(int *p) {
|
||||
return *p;
|
||||
}
|
||||
|
||||
static void handle_sigsegv(int num, siginfo_t *info, void *_context) {
|
||||
printf("SIGSEGV Caught\n");
|
||||
assert(num == SIGSEGV);
|
||||
assert(info->si_signo == SIGSEGV);
|
||||
|
||||
ucontext_t *ucontext = _context;
|
||||
mcontext_t *mcontext = &ucontext->uc_mcontext;
|
||||
// TODO: how long is the instruction?
|
||||
// The faulty instruction should be `idiv %esi` (f7 fe)
|
||||
mcontext->gregs[REG_RIP] += 2;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int test_handle_sigsegv() {
|
||||
#ifdef SGX_MODE_SIM
|
||||
printf("WARNING: Skip this test case as we do not support "
|
||||
"capturing hardware exception in SGX simulation mode\n");
|
||||
return 0;
|
||||
#else
|
||||
// Set up a signal handler that handles divide-by-zero exception
|
||||
struct sigaction new_action, old_action;
|
||||
new_action.sa_sigaction = handle_sigsegv;
|
||||
new_action.sa_flags = SA_SIGINFO;
|
||||
if (sigaction(SIGSEGV, &new_action, &old_action) < 0) {
|
||||
THROW_ERROR("registering new signal handler failed");
|
||||
}
|
||||
if (old_action.sa_handler != SIG_DFL) {
|
||||
THROW_ERROR("unexpected old sig handler");
|
||||
}
|
||||
|
||||
int *addr = NULL;
|
||||
volatile int val = read_maybe_null(addr);
|
||||
|
||||
printf("Signal handler successfully jumped over a null-dereferencing instruction\n");
|
||||
|
||||
if (sigaction(SIGSEGV, &old_action, NULL) < 0) {
|
||||
THROW_ERROR("restoring old signal handler failed");
|
||||
}
|
||||
return 0;
|
||||
#endif /* SGX_MODE_SIM */
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Test handle signal on alternate signal stack
|
||||
// ============================================================================
|
||||
@ -364,7 +414,8 @@ static test_case_t test_cases[] = {
|
||||
TEST_CASE(test_raise),
|
||||
TEST_CASE(test_abort),
|
||||
TEST_CASE(test_kill),
|
||||
TEST_CASE(test_catch_fault),
|
||||
TEST_CASE(test_handle_sigfpe),
|
||||
TEST_CASE(test_handle_sigsegv),
|
||||
TEST_CASE(test_sigaltstack),
|
||||
TEST_CASE(test_sigchld),
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user