|
|
@@ -44,11 +44,24 @@ enclave_entry:
|
|
|
# from a OCALL in the untrusted PAL. Attackers can manipulate RDI
|
|
|
# to deceive the trusted PAL.
|
|
|
|
|
|
- # A safe design: check if %gs:SGX_EXIT_TARGET is ever assigned
|
|
|
- movq %gs:SGX_EXIT_TARGET, %rcx
|
|
|
- cmpq $0, %rcx
|
|
|
+ # This thread can be interrupted but then the above check branches to
|
|
|
+ # .Lhandle_resume. So the outside can't re-enter the checks below in
|
|
|
+ # the middle.
|
|
|
+
|
|
|
+ # Only jump to .Lreturn_from_ocall if we have prepared the stack for
|
|
|
+ # it.
|
|
|
+ cmpq $0, %gs:SGX_OCALL_PREPARED
|
|
|
jne .Lreturn_from_ocall
|
|
|
|
|
|
+ # Ecalls are only used to start a thread (either the main or an
|
|
|
+ # additional thread). So per thread we should only get exactly one
|
|
|
+ # ecall. Enforce this here.
|
|
|
+ cmpq $0, %gs:SGX_ECALL_CALLED
|
|
|
+ je 1f
|
|
|
+ FAIL_LOOP
|
|
|
+1:
|
|
|
+ movq $1, %gs:SGX_ECALL_CALLED
|
|
|
+
|
|
|
# PAL convention:
|
|
|
# RDI - index in ecall_table
|
|
|
# RSI - prointer to ecall arguments
|
|
|
@@ -244,6 +257,8 @@ sgx_ocall:
|
|
|
|
|
|
pushq %rbp
|
|
|
|
|
|
+ movq $1, %gs:SGX_OCALL_PREPARED
|
|
|
+
|
|
|
jmp .Leexit
|
|
|
|
|
|
.Leexit:
|
|
|
@@ -272,6 +287,8 @@ sgx_ocall:
|
|
|
# RDI - return value
|
|
|
# RSI - external event (if there is any)
|
|
|
|
|
|
+ movq $0, %gs:SGX_OCALL_PREPARED
|
|
|
+
|
|
|
movq %rdi, %rax
|
|
|
|
|
|
# restore FSBASE if necessary
|