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
|
diff --git a/samplecode/unit-test/enclave/src/lib.rs b/samplecode/unit-test/enclave/src/lib.rs
|
||||||
index b9ea49be..d740753f 100644
|
index b9ea49be..d740753f 100644
|
||||||
--- a/samplecode/unit-test/enclave/src/lib.rs
|
--- a/samplecode/unit-test/enclave/src/lib.rs
|
||||||
@ -356,3 +370,78 @@ index 3c2db3a4..f96cd9e8 100644
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* intel sgx sdk 2.0 */
|
/* 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" }
|
sgx_tstd = { path = "../../deps/rust-sgx-sdk/sgx_tstd" }
|
||||||
|
|
||||||
[features]
|
[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.
|
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.
|
integrity_only_opt = [] # Clear bss only. It should be disabled if checking memory reads.
|
||||||
sgx_file_cache = [] # Cache SgxFile objects. Invalidation is unimplemented.
|
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]
|
[target.'cfg(not(target_env = "sgx"))'.dependencies]
|
||||||
xmas-elf = { path = "../../deps/xmas-elf" }
|
xmas-elf = { path = "../../deps/xmas-elf" }
|
||||||
|
@ -37,9 +37,7 @@ pub fn do_handle_exception(
|
|||||||
user_context: *mut CpuContext,
|
user_context: *mut CpuContext,
|
||||||
) -> Result<isize> {
|
) -> Result<isize> {
|
||||||
let info = unsafe { &mut *info };
|
let info = unsafe { &mut *info };
|
||||||
if info.exception_type != sgx_exception_type_t::SGX_EXCEPTION_HARDWARE {
|
check_exception_type(info.exception_type)?;
|
||||||
return_errno!(EINVAL, "Can only handle hardware exceptions");
|
|
||||||
}
|
|
||||||
|
|
||||||
let user_context = unsafe { &mut *user_context };
|
let user_context = unsafe { &mut *user_context };
|
||||||
*user_context = CpuContext::from_sgx(&info.cpu_context);
|
*user_context = CpuContext::from_sgx(&info.cpu_context);
|
||||||
@ -72,3 +70,32 @@ pub fn do_handle_exception(
|
|||||||
|
|
||||||
Ok(0)
|
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 {
|
pub struct FaultSignal {
|
||||||
num: SigNum,
|
num: SigNum,
|
||||||
code: i32,
|
code: i32,
|
||||||
|
addr: Option<u64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FaultSignal {
|
impl FaultSignal {
|
||||||
pub fn new(info: &sgx_exception_info_t) -> Self {
|
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::*;
|
use sgx_exception_vector_t::*;
|
||||||
let (num, code) = match info.exception_vector {
|
let (num, code, addr) = match info.exception_vector {
|
||||||
// Divider exception
|
// Divider exception
|
||||||
SGX_EXCEPTION_VECTOR_DE => (SIGFPE, FPE_INTDIV),
|
SGX_EXCEPTION_VECTOR_DE => (SIGFPE, FPE_INTDIV, None),
|
||||||
// Floating-point exception
|
// Floating-point exception
|
||||||
SGX_EXCEPTION_VECTOR_MF |
|
SGX_EXCEPTION_VECTOR_MF |
|
||||||
// SIMD floating-point exception
|
// SIMD floating-point exception
|
||||||
SGX_EXCEPTION_VECTOR_XM => (SIGFPE, FPE_FLTDIV),
|
SGX_EXCEPTION_VECTOR_XM => (SIGFPE, FPE_FLTDIV, None),
|
||||||
// Invalid opcode exception
|
// Invalid opcode exception
|
||||||
SGX_EXCEPTION_VECTOR_UD |
|
SGX_EXCEPTION_VECTOR_UD |
|
||||||
// Debug exception: should not occur in enclave; treat is as #UD
|
// Debug exception: should not occur in enclave; treat is as #UD
|
||||||
SGX_EXCEPTION_VECTOR_DB |
|
SGX_EXCEPTION_VECTOR_DB |
|
||||||
// Break point exception: should not occur in enclave; treat is as #UD
|
// 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
|
// Bound range exception
|
||||||
SGX_EXCEPTION_VECTOR_BR => (SIGSEGV, SEGV_BNDERR),
|
SGX_EXCEPTION_VECTOR_BR => (SIGSEGV, SEGV_BNDERR, None),
|
||||||
// Alignment check exception
|
// Alignment check exception
|
||||||
SGX_EXCEPTION_VECTOR_AC => (SIGBUS, BUS_ADRALN),
|
SGX_EXCEPTION_VECTOR_AC => (SIGBUS, BUS_ADRALN, None),
|
||||||
// TODO: handle page fault and general protection exceptions
|
// Page fault exception
|
||||||
_ => panic!("illegal exception: cannot be converted to signal"),
|
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
|
||||||
|
};
|
||||||
|
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 }
|
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 {
|
fn to_info(&self) -> siginfo_t {
|
||||||
let info = siginfo_t::new(self.num, self.code);
|
let mut info = siginfo_t::new(self.num, self.code);
|
||||||
// TODO: set info.si_addr
|
info.set_si_addr(self.addr.unwrap_or_default() as *const c_void);
|
||||||
info
|
info
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -228,7 +228,7 @@ int div_maybe_zero(int x, int y) {
|
|||||||
return x / y;
|
return x / y;
|
||||||
}
|
}
|
||||||
|
|
||||||
int test_catch_fault() {
|
int test_handle_sigfpe() {
|
||||||
#ifdef SGX_MODE_SIM
|
#ifdef SGX_MODE_SIM
|
||||||
printf("WARNING: Skip this test case as we do not support "
|
printf("WARNING: Skip this test case as we do not support "
|
||||||
"capturing hardware exception in SGX simulation mode\n");
|
"capturing hardware exception in SGX simulation mode\n");
|
||||||
@ -261,6 +261,56 @@ int test_catch_fault() {
|
|||||||
#endif /* SGX_MODE_SIM */
|
#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
|
// Test handle signal on alternate signal stack
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@ -364,7 +414,8 @@ static test_case_t test_cases[] = {
|
|||||||
TEST_CASE(test_raise),
|
TEST_CASE(test_raise),
|
||||||
TEST_CASE(test_abort),
|
TEST_CASE(test_abort),
|
||||||
TEST_CASE(test_kill),
|
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_sigaltstack),
|
||||||
TEST_CASE(test_sigchld),
|
TEST_CASE(test_sigchld),
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user