From c8a2a2ee873d84e72ca0fb5c724f258e65b6d866 Mon Sep 17 00:00:00 2001 From: Dmitrii Kuvaiskii Date: Fri, 15 Nov 2019 16:53:40 -0800 Subject: [PATCH] [Pal/Linux-SGX] Clear the Alignment Check (AC) flag in RFLAGS upon enclave entry When the AC flag is set, any unaligned data access forces an #AC exception. This constitutes a subtle side channel, similar to other controlled-channel attacks (e.g., page fault attacks on SGX enclaves). These vulnerability was discovered and disclosed by David Oswald, Jo Van Bulck, and others. --- Pal/src/host/Linux-SGX/enclave_entry.S | 22 ++++++++++++++++++---- Pal/src/host/Linux-SGX/sgx_arch.h | 1 + 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/Pal/src/host/Linux-SGX/enclave_entry.S b/Pal/src/host/Linux-SGX/enclave_entry.S index a4ed70bc..5f263348 100644 --- a/Pal/src/host/Linux-SGX/enclave_entry.S +++ b/Pal/src/host/Linux-SGX/enclave_entry.S @@ -76,7 +76,7 @@ enclave_entry: # push untrusted stack address to RCX movq %rsp, %rcx - # switch to enclve stack: enclave base + %gs:SGX_INITIAL_STACK_OFFSET + # switch to enclave stack: enclave base + %gs:SGX_INITIAL_STACK_OFFSET addq %gs:SGX_INITIAL_STACK_OFFSET, %rbx movq %rbx, %rsp @@ -91,6 +91,12 @@ enclave_entry: xorq %r14, %r14 xorq %r15, %r15 + # clear the Alignment Check flag (%rFLAGS.AC) to prevent #AC-fault side channel; + # this overrides 8B on enclave stack but stack is not used at this point anyway + pushfq + andq $(~RFLAGS_AC), (%rsp) + popfq + # Clear "extended" state (FPU aka x87, SSE, AVX, ...). # TODO: We currently clear only state covered by FXRSTOR but not by XRSTOR # (e.g., no clearing of YMM/ZMM regs). This is because we didn't read @@ -322,7 +328,7 @@ enclave_entry: movq %rsi, SGX_GPR_RSP(%rbx) movq $0, %gs:SGX_STACK movq $0, %gs:SGX_OCALL_PREPARED - andq $(~RFLAGS_DF), SGX_GPR_RFLAGS(%rbx) + andq $(~(RFLAGS_DF | RFLAGS_AC)), SGX_GPR_RFLAGS(%rbx) jmp .Leexit_exception .Lsetup_exception_handler: @@ -405,8 +411,9 @@ enclave_entry: subq $8, %rsi movq %rsi, SGX_GPR_RSP(%rbx) - # Clear RFLAGS.DF to conform to the SysV ABI. - andq $(~RFLAGS_DF), SGX_GPR_RFLAGS(%rbx) + # clear RFLAGS.DF to conform to the SysV ABI, clear RFLAGS.AC to prevent + # the #AC-fault side channel + andq $(~(RFLAGS_DF | RFLAGS_AC)), SGX_GPR_RFLAGS(%rbx) # new RIP is the exception handler leaq _DkExceptionHandler(%rip), %rdi @@ -631,6 +638,13 @@ __morestack: cmpq $0, %rsi je .Lno_external_event + + # clear the Alignment Check flag (%rFLAGS.AC) to prevent #AC-fault side channel; + # this overrides 8B on enclave stack but these 8B will be overwritten with RAX anyway + pushfq + andq $(~RFLAGS_AC), (%rsp) + popfq + pushq %rax movq %rsi, %rdi movq %rsp, %rsi diff --git a/Pal/src/host/Linux-SGX/sgx_arch.h b/Pal/src/host/Linux-SGX/sgx_arch.h index 66c68bfe..33df23c8 100644 --- a/Pal/src/host/Linux-SGX/sgx_arch.h +++ b/Pal/src/host/Linux-SGX/sgx_arch.h @@ -383,6 +383,7 @@ typedef uint8_t sgx_key_128bit_t[16]; #define RETURN_FROM_OCALL 0xffffffffffffffff #define RFLAGS_DF (1<<10) +#define RFLAGS_AC (1<<18) #pragma pack(pop) #endif /* SGX_ARCH_H */