|
@@ -135,8 +135,40 @@ enclave_entry:
|
|
|
retq
|
|
|
#endif
|
|
|
|
|
|
+ ## There is a race between host signal delivery and restoring %rsp
|
|
|
+ ## in this entry code. We must be careful to setup %rsp.
|
|
|
+ ##
|
|
|
+ ## Race scenario
|
|
|
+ ## 1. We are inside the enclave but %rsp isn't restored yet to something
|
|
|
+ ## inside the enclave. That's for example the case when returning from
|
|
|
+ ## an ocall.
|
|
|
+ ## 2. The enclave gets interrupted. The not restored %rsp is pushed into
|
|
|
+ ## SGX_GPR_RSP by the processor.
|
|
|
+ ## 3. The host enters the enclave again and indicated that there's a new
|
|
|
+ ## signal.
|
|
|
+ ## 4. The code after .Lhandle_exception pushes stuff on the untrusted
|
|
|
+ ## stack (because SGX_GPR_RSP points there) and then diverts %rip to
|
|
|
+ ## execute the event handler after ERESUME (which will use the untrusted
|
|
|
+ ## stack).
|
|
|
+ ##
|
|
|
+ ## The solution is to have a "fallback" value stored in SGX_STACK.
|
|
|
+ ## If SGX_STACK == 0, then %rsp was correctly restored during
|
|
|
+ ## Lreturn_from_ocall and the interrupt happened after that, so the CPU
|
|
|
+ ## pushed the restored %rsp into SGX_GPR_RSP, thus we can safely use
|
|
|
+ ## SGX_GPR_RSP.
|
|
|
+ ## However, if SGX_STACK != 0, this indicates that the interrupt came
|
|
|
+ ## before xchgq %rsp, %gs:SGX_STACK and %rsp was not yet restored,
|
|
|
+ ## so the CPU pushed some untrusted %rsp into SGX_GPR_RSP. Thus, we
|
|
|
+ ## cannot trust value in SGX_GPR_RSP and should fall-back to using
|
|
|
+ ## SGX_STACK (which was updated with the last known good in-enclave
|
|
|
+ ## %rsp during Leexit).
|
|
|
.Lhandle_exception:
|
|
|
movq SGX_GPR_RSP(%rbx), %rsi
|
|
|
+ movq %gs:SGX_STACK, %rax
|
|
|
+ cmpq $0, %rax
|
|
|
+ je 1f
|
|
|
+ movq %rax, %rsi
|
|
|
+1:
|
|
|
subq $0x90, %rsi
|
|
|
|
|
|
# we have exitinfo in RDI, swap with the one on GPR
|
|
@@ -232,12 +264,9 @@ sgx_ocall:
|
|
|
fxsave (%rsp)
|
|
|
|
|
|
pushq %rbp
|
|
|
- movq %rsp, %gs:SGX_STACK
|
|
|
|
|
|
jmp .Leexit
|
|
|
|
|
|
-.Lexception_handler:
|
|
|
-
|
|
|
.Leexit:
|
|
|
xorq %rdx, %rdx
|
|
|
xorq %r8, %r8
|
|
@@ -250,6 +279,7 @@ sgx_ocall:
|
|
|
xorq %r15, %r15
|
|
|
xorq %rbp, %rbp
|
|
|
|
|
|
+ movq %rsp, %gs:SGX_STACK
|
|
|
movq %gs:SGX_USTACK, %rsp
|
|
|
andq $STACK_ALIGN, %rsp
|
|
|
|
|
@@ -273,7 +303,8 @@ sgx_ocall:
|
|
|
.Lno_fsbase:
|
|
|
|
|
|
# restore the stack
|
|
|
- movq %gs:SGX_STACK, %rsp
|
|
|
+ movq $0, %rsp
|
|
|
+ xchgq %rsp, %gs:SGX_STACK
|
|
|
|
|
|
popq %rbp
|
|
|
fxrstor (%rsp)
|