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 | ||||
|                 }; | ||||
|                 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 { | ||||
|         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