]> git.lizzy.rs Git - rust.git/commitdiff
SGX target: improve panic & exit handling
authorJethro Beekman <jethro@fortanix.com>
Tue, 29 Jan 2019 11:40:22 +0000 (17:10 +0530)
committerJethro Beekman <jethro@fortanix.com>
Tue, 29 Jan 2019 11:42:56 +0000 (17:12 +0530)
src/libstd/sys/sgx/abi/entry.S
src/libstd/sys/sgx/abi/panic.rs
src/libstd/sys/sgx/abi/usercalls/mod.rs
src/libstd/sys/sgx/mod.rs

index ac7f95d4eae80fc587edbc548a21f18a66707f04..9b46c2180d9a25a3a05853b6872b85272ff03f6d 100644 (file)
@@ -66,7 +66,7 @@ IMAGE_BASE:
     globvar EH_FRM_HDR_SIZE 8
 
 .Lreentry_panic_msg:
-    .asciz "Re-entered panicked enclave!"
+    .asciz "Re-entered aborted enclave!"
 .Lreentry_panic_msg_end:
 
 .Lusercall_panic_msg:
@@ -80,7 +80,7 @@ IMAGE_BASE:
     .org .+48 /*  reserved bits */
 
 .data
-.Lpanicked:
+.Laborted:
     .byte 0
 
 /*  TCS local storage section */
@@ -134,6 +134,9 @@ sgx_entry:
     jz .Lskip_debug_init
     mov %r10,%gs:tcsls_debug_panic_buf_ptr
 .Lskip_debug_init:
+/*  check for abort */
+    bt $0,.Laborted(%rip)
+    jc .Lreentry_panic
 /*  check if returning from usercall */
     mov %gs:tcsls_last_rsp,%r11
     test %r11,%r11
@@ -164,9 +167,6 @@ sgx_entry:
     mov %r14,%r8
     mov %r15,%r9
 .Lskip_init:
-/*  check for panic */
-    bt $0,.Lpanicked(%rip)
-    jc .Lreentry_panic
 /*  call into main entry point */
     load_tcsls_flag_secondary_bool cx /* RCX = entry() argument: secondary: bool */
     call entry /* RDI, RSI, RDX, R8, R9 passed in from userspace */
@@ -237,18 +237,18 @@ sgx_entry:
     stmxcsr (%rsp)
 .endm
 
-.global panic_exit
-panic_exit:
+.global usercall_exit
+usercall_exit:
 /* save registers in DEBUG mode, so that debugger can reconstruct the stack */
     testb $0xff,DEBUG(%rip)
     jz .Lskip_save_registers
     push_callee_saved_registers
     movq %rsp,%gs:tcsls_panic_last_rsp
 .Lskip_save_registers:
-/* set panicked bit */
-    movb $1,.Lpanicked(%rip)
+/* set aborted bit */
+    movb $1,.Laborted(%rip)
 /* call usercall exit(true) */
-    mov $1,%esi   /*  RSI = usercall() argument: panic = true */
+    /* NOP: mov %rsi,%rsi */ /*  RSI = usercall() argument: panic */
     xor %rdx,%rdx /*  RDX cleared */
     movq $usercall_nr_exit,%rdi /*  RDI = usercall exit */
     jmp .Lexit
index 5ace7fb3368b66be9ad718b709f09afc8835ae8d..d23fa9a9ec6f9783c4c653101d8a22b1bc49f271 100644 (file)
@@ -1,12 +1,18 @@
+use super::usercalls::alloc::UserRef;
+use cmp;
 use io::{self, Write};
-use slice::from_raw_parts_mut;
+use mem;
 
 extern "C" {
     fn take_debug_panic_buf_ptr() -> *mut u8;
     static DEBUG: u8;
 }
 
-pub(crate) struct SgxPanicOutput(Option<&'static mut [u8]>);
+pub(crate) struct SgxPanicOutput(Option<&'static mut UserRef<[u8]>>);
+
+fn empty_user_slice() -> &'static mut UserRef<[u8]> {
+    unsafe { UserRef::from_raw_parts_mut(1 as *mut u8, 0) }
+}
 
 impl SgxPanicOutput {
     pub(crate) fn new() -> Option<Self> {
@@ -17,32 +23,36 @@ pub(crate) fn new() -> Option<Self> {
         }
     }
 
-    fn init(&mut self) -> &mut &'static mut [u8] {
+    fn init(&mut self) -> &mut &'static mut UserRef<[u8]> {
         self.0.get_or_insert_with(|| unsafe {
             let ptr = take_debug_panic_buf_ptr();
             if ptr.is_null() {
-                &mut []
+                empty_user_slice()
             } else {
-                from_raw_parts_mut(ptr, 1024)
+                UserRef::from_raw_parts_mut(ptr, 1024)
             }
         })
     }
 }
 
 impl Write for SgxPanicOutput {
-    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
-        self.init().write(buf)
+    fn write(&mut self, src: &[u8]) -> io::Result<usize> {
+        let dst = mem::replace(self.init(), empty_user_slice());
+        let written = cmp::min(src.len(), dst.len());
+        dst[..written].copy_from_enclave(&src[..written]);
+        self.0 = Some(&mut dst[written..]);
+        Ok(written)
     }
 
     fn flush(&mut self) -> io::Result<()> {
-        self.init().flush()
+        Ok(())
     }
 }
 
 #[no_mangle]
 pub extern "C" fn panic_msg(msg: &str) -> ! {
     let _ = SgxPanicOutput::new().map(|mut out| out.write(msg.as_bytes()));
-    unsafe { panic_exit(); }
+    unsafe { usercall_exit(true); }
 }
 
-extern "C" { pub fn panic_exit() -> !; }
+extern "C" { pub fn usercall_exit(panic: bool) -> !; }
index 58903761ebe400450c19c8f006c6bc18b9aa0e68..4e889c172ef38109fd9b2e2991b89007511bfa85 100644 (file)
@@ -119,7 +119,7 @@ pub unsafe fn launch_thread() -> IoResult<()> {
 /// Usercall `exit`. See the ABI documentation for more information.
 #[unstable(feature = "sgx_platform", issue = "56975")]
 pub fn exit(panic: bool) -> ! {
-    unsafe { raw::exit(panic) }
+    unsafe { super::panic::usercall_exit(panic) }
 }
 
 /// Usercall `wait`. See the ABI documentation for more information.
index 7f8550490a19968a69c81f24ad94ea593c409d29..f2593c35bed14c6c79103d2716e6b0a098e9627f 100644 (file)
@@ -125,7 +125,7 @@ pub unsafe fn strlen(mut s: *const c_char) -> usize {
 }
 
 pub unsafe fn abort_internal() -> ! {
-    abi::panic::panic_exit()
+    abi::panic::usercall_exit(true)
 }
 
 pub fn hashmap_random_keys() -> (u64, u64) {