Skip to content

Commit 65c2996

Browse files
authored
Rollup merge of rust-lang#57971 - jethrogb:jb/sgx-panic, r=alexcrichton
SGX target: improve panic & exit handling Implement this part of the spec: > The enclave must not rely on userspace to terminate other threads still running. Similarly, the enclave must not trust that it will no longer be entered by userspace, and it must safeguard against that in the entrypoints. Also use `UserRef` to access panic buffer r? @alexcrichton cc @VardhanThigle
2 parents f255361 + a75ae00 commit 65c2996

File tree

4 files changed

+32
-22
lines changed

4 files changed

+32
-22
lines changed

src/libstd/sys/sgx/abi/entry.S

+10-10
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ IMAGE_BASE:
6666
globvar EH_FRM_HDR_SIZE 8
6767

6868
.Lreentry_panic_msg:
69-
.asciz "Re-entered panicked enclave!"
69+
.asciz "Re-entered aborted enclave!"
7070
.Lreentry_panic_msg_end:
7171

7272
.Lusercall_panic_msg:
@@ -80,7 +80,7 @@ IMAGE_BASE:
8080
.org .+48 /* reserved bits */
8181

8282
.data
83-
.Lpanicked:
83+
.Laborted:
8484
.byte 0
8585

8686
/* TCS local storage section */
@@ -134,6 +134,9 @@ sgx_entry:
134134
jz .Lskip_debug_init
135135
mov %r10,%gs:tcsls_debug_panic_buf_ptr
136136
.Lskip_debug_init:
137+
/* check for abort */
138+
bt $0,.Laborted(%rip)
139+
jc .Lreentry_panic
137140
/* check if returning from usercall */
138141
mov %gs:tcsls_last_rsp,%r11
139142
test %r11,%r11
@@ -164,9 +167,6 @@ sgx_entry:
164167
mov %r14,%r8
165168
mov %r15,%r9
166169
.Lskip_init:
167-
/* check for panic */
168-
bt $0,.Lpanicked(%rip)
169-
jc .Lreentry_panic
170170
/* call into main entry point */
171171
load_tcsls_flag_secondary_bool cx /* RCX = entry() argument: secondary: bool */
172172
call entry /* RDI, RSI, RDX, R8, R9 passed in from userspace */
@@ -237,18 +237,18 @@ sgx_entry:
237237
stmxcsr (%rsp)
238238
.endm
239239

240-
.global panic_exit
241-
panic_exit:
240+
.global usercall_exit
241+
usercall_exit:
242242
/* save registers in DEBUG mode, so that debugger can reconstruct the stack */
243243
testb $0xff,DEBUG(%rip)
244244
jz .Lskip_save_registers
245245
push_callee_saved_registers
246246
movq %rsp,%gs:tcsls_panic_last_rsp
247247
.Lskip_save_registers:
248-
/* set panicked bit */
249-
movb $1,.Lpanicked(%rip)
248+
/* set aborted bit */
249+
movb $1,.Laborted(%rip)
250250
/* call usercall exit(true) */
251-
mov $1,%esi /* RSI = usercall() argument: panic = true */
251+
/* NOP: mov %rsi,%rsi */ /* RSI = usercall() argument: panic */
252252
xor %rdx,%rdx /* RDX cleared */
253253
movq $usercall_nr_exit,%rdi /* RDI = usercall exit */
254254
jmp .Lexit

src/libstd/sys/sgx/abi/panic.rs

+20-10
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
1+
use super::usercalls::alloc::UserRef;
2+
use cmp;
13
use io::{self, Write};
2-
use slice::from_raw_parts_mut;
4+
use mem;
35

46
extern "C" {
57
fn take_debug_panic_buf_ptr() -> *mut u8;
68
static DEBUG: u8;
79
}
810

9-
pub(crate) struct SgxPanicOutput(Option<&'static mut [u8]>);
11+
pub(crate) struct SgxPanicOutput(Option<&'static mut UserRef<[u8]>>);
12+
13+
fn empty_user_slice() -> &'static mut UserRef<[u8]> {
14+
unsafe { UserRef::from_raw_parts_mut(1 as *mut u8, 0) }
15+
}
1016

1117
impl SgxPanicOutput {
1218
pub(crate) fn new() -> Option<Self> {
@@ -17,32 +23,36 @@ impl SgxPanicOutput {
1723
}
1824
}
1925

20-
fn init(&mut self) -> &mut &'static mut [u8] {
26+
fn init(&mut self) -> &mut &'static mut UserRef<[u8]> {
2127
self.0.get_or_insert_with(|| unsafe {
2228
let ptr = take_debug_panic_buf_ptr();
2329
if ptr.is_null() {
24-
&mut []
30+
empty_user_slice()
2531
} else {
26-
from_raw_parts_mut(ptr, 1024)
32+
UserRef::from_raw_parts_mut(ptr, 1024)
2733
}
2834
})
2935
}
3036
}
3137

3238
impl Write for SgxPanicOutput {
33-
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
34-
self.init().write(buf)
39+
fn write(&mut self, src: &[u8]) -> io::Result<usize> {
40+
let dst = mem::replace(self.init(), empty_user_slice());
41+
let written = cmp::min(src.len(), dst.len());
42+
dst[..written].copy_from_enclave(&src[..written]);
43+
self.0 = Some(&mut dst[written..]);
44+
Ok(written)
3545
}
3646

3747
fn flush(&mut self) -> io::Result<()> {
38-
self.init().flush()
48+
Ok(())
3949
}
4050
}
4151

4252
#[no_mangle]
4353
pub extern "C" fn panic_msg(msg: &str) -> ! {
4454
let _ = SgxPanicOutput::new().map(|mut out| out.write(msg.as_bytes()));
45-
unsafe { panic_exit(); }
55+
unsafe { usercall_exit(true); }
4656
}
4757

48-
extern "C" { pub fn panic_exit() -> !; }
58+
extern "C" { pub fn usercall_exit(panic: bool) -> !; }

src/libstd/sys/sgx/abi/usercalls/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ pub unsafe fn launch_thread() -> IoResult<()> {
119119
/// Usercall `exit`. See the ABI documentation for more information.
120120
#[unstable(feature = "sgx_platform", issue = "56975")]
121121
pub fn exit(panic: bool) -> ! {
122-
unsafe { raw::exit(panic) }
122+
unsafe { super::panic::usercall_exit(panic) }
123123
}
124124

125125
/// Usercall `wait`. See the ABI documentation for more information.

src/libstd/sys/sgx/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ pub unsafe fn strlen(mut s: *const c_char) -> usize {
125125
}
126126

127127
pub unsafe fn abort_internal() -> ! {
128-
abi::panic::panic_exit()
128+
abi::panic::usercall_exit(true)
129129
}
130130

131131
pub fn hashmap_random_keys() -> (u64, u64) {

0 commit comments

Comments
 (0)