From aeedc9dea9e0460488e0b6ce7fe3aaf50395774c Mon Sep 17 00:00:00 2001 From: Raoul Strackx Date: Fri, 7 Feb 2020 10:37:53 +0100 Subject: [PATCH 1/3] Corrected ac_mitigation patch. That patch used the untrusted stack to clear rflags during enclave (re-)entry --- src/libstd/sys/sgx/abi/entry.S | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/libstd/sys/sgx/abi/entry.S b/src/libstd/sys/sgx/abi/entry.S index a3e059e813173..7c273a8a83d30 100644 --- a/src/libstd/sys/sgx/abi/entry.S +++ b/src/libstd/sys/sgx/abi/entry.S @@ -134,6 +134,17 @@ elf_entry: ud2 /* should not be reached */ /* end elf_entry */ +/* This code needs to be called *after* the enclave stack has been setup. */ +/* There are 3 places where this needs to happen, so this is put in a macro. */ +.macro sanitize_rflags +/* Sanitize rflags received from user */ +/* - DF flag: x86-64 ABI requires DF to be unset at function entry/exit */ +/* - AC flag: AEX on misaligned memory accesses leaks side channel info */ + pushfq + andq $~0x40400, (%rsp) + popfq +.endm + .text .global sgx_entry .type sgx_entry,function @@ -150,13 +161,6 @@ sgx_entry: stmxcsr %gs:tcsls_user_mxcsr fnstcw %gs:tcsls_user_fcw -/* reset user state */ -/* - DF flag: x86-64 ABI requires DF to be unset at function entry/exit */ -/* - AC flag: AEX on misaligned memory accesses leaks side channel info */ - pushfq - andq $~0x40400, (%rsp) - popfq - /* check for debug buffer pointer */ testb $0xff,DEBUG(%rip) jz .Lskip_debug_init @@ -179,6 +183,7 @@ sgx_entry: lea IMAGE_BASE(%rip),%rax add %rax,%rsp mov %rsp,%gs:tcsls_tos + sanitize_rflags /* call tcs_init */ /* store caller-saved registers in callee-saved registers */ mov %rdi,%rbx @@ -194,7 +199,10 @@ sgx_entry: mov %r13,%rdx mov %r14,%r8 mov %r15,%r9 + jmp .Lafter_init .Lskip_init: + sanitize_rflags +.Lafter_init: /* 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 */ @@ -292,6 +300,7 @@ usercall: movq $0,%gs:tcsls_last_rsp /* restore callee-saved state, cf. "save" above */ mov %r11,%rsp + sanitize_rflags ldmxcsr (%rsp) fldcw 4(%rsp) add $8, %rsp From 236ab6e6d631f073a8c3c7439af6b2ec58ce1f25 Mon Sep 17 00:00:00 2001 From: Raoul Strackx Date: Fri, 7 Feb 2020 10:49:47 +0100 Subject: [PATCH 2/3] sanitize MXCSR/FPU control registers --- src/libstd/sys/sgx/abi/entry.S | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/libstd/sys/sgx/abi/entry.S b/src/libstd/sys/sgx/abi/entry.S index 7c273a8a83d30..a08caec3c2b35 100644 --- a/src/libstd/sys/sgx/abi/entry.S +++ b/src/libstd/sys/sgx/abi/entry.S @@ -30,6 +30,14 @@ IMAGE_BASE: /* We can store a bunch of data in the gap between MXCSR and the XSAVE header */ +/* MXCSR initialization value for ABI */ +.Lmxcsr_init: + .int 0x1f80 + +/* x87 FPU control word initialization value for ABI */ +.Lfpucw_init: + .int 0x037f + /* The following symbols point at read-only data that will be filled in by the */ /* post-linker. */ @@ -173,6 +181,9 @@ sgx_entry: mov %gs:tcsls_last_rsp,%r11 test %r11,%r11 jnz .Lusercall_ret +/* reset user state */ + ldmxcsr .Lmxcsr_init(%rip) + fldcw .Lfpucw_init(%rip) /* setup stack */ mov %gs:tcsls_tos,%rsp /* initially, RSP is not set to the correct value */ /* here. This is fixed below under "adjust stack". */ From 71b9ed4a36748be01826063951310a2da2717a9b Mon Sep 17 00:00:00 2001 From: Jethro Beekman Date: Mon, 10 Feb 2020 21:00:22 +0100 Subject: [PATCH 3/3] Avoid jumping to Rust code with user %rsp (reentry_panic) --- src/libstd/sys/sgx/abi/entry.S | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/libstd/sys/sgx/abi/entry.S b/src/libstd/sys/sgx/abi/entry.S index a08caec3c2b35..ed4db287229dc 100644 --- a/src/libstd/sys/sgx/abi/entry.S +++ b/src/libstd/sys/sgx/abi/entry.S @@ -144,13 +144,15 @@ elf_entry: /* This code needs to be called *after* the enclave stack has been setup. */ /* There are 3 places where this needs to happen, so this is put in a macro. */ -.macro sanitize_rflags +.macro entry_sanitize_final /* Sanitize rflags received from user */ /* - DF flag: x86-64 ABI requires DF to be unset at function entry/exit */ /* - AC flag: AEX on misaligned memory accesses leaks side channel info */ pushfq andq $~0x40400, (%rsp) popfq + bt $0,.Laborted(%rip) + jc .Lreentry_panic .endm .text @@ -174,9 +176,6 @@ 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 @@ -194,7 +193,7 @@ sgx_entry: lea IMAGE_BASE(%rip),%rax add %rax,%rsp mov %rsp,%gs:tcsls_tos - sanitize_rflags + entry_sanitize_final /* call tcs_init */ /* store caller-saved registers in callee-saved registers */ mov %rdi,%rbx @@ -212,7 +211,7 @@ sgx_entry: mov %r15,%r9 jmp .Lafter_init .Lskip_init: - sanitize_rflags + entry_sanitize_final .Lafter_init: /* call into main entry point */ load_tcsls_flag_secondary_bool cx /* RCX = entry() argument: secondary: bool */ @@ -311,10 +310,10 @@ usercall: movq $0,%gs:tcsls_last_rsp /* restore callee-saved state, cf. "save" above */ mov %r11,%rsp - sanitize_rflags ldmxcsr (%rsp) fldcw 4(%rsp) add $8, %rsp + entry_sanitize_final pop %rbx pop %rbp pop %r12