From ef343cdf9db24cd6689cf16ecefd40275aababcb Mon Sep 17 00:00:00 2001 From: Dmitrii Kuvaiskii Date: Tue, 14 May 2019 19:44:31 -0700 Subject: [PATCH] [Pal/Linux-SGX] Instruct GDB to bridge enclave-untrusted stacks Before, GDB did not know about enclave stack frames when debugging untrusted OCALL functions. This patch bridges untrusted stack to its corresponding enclave stack by setting RBP to point to the first enclave stack frame. This functionality is only enabled if Graphene-SGX is built with DEBUG flag. Without DEBUG, RBP is cleared to prevent leakage of the address of enclave stack. --- Pal/src/host/Linux-SGX/Makefile | 1 + Pal/src/host/Linux-SGX/enclave_entry.S | 29 ++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/Pal/src/host/Linux-SGX/Makefile b/Pal/src/host/Linux-SGX/Makefile index eb48159e..a97dfbae 100644 --- a/Pal/src/host/Linux-SGX/Makefile +++ b/Pal/src/host/Linux-SGX/Makefile @@ -23,6 +23,7 @@ all: $(host_files) ifeq ($(DEBUG),1) CC += -gdwarf-2 -g3 CFLAGS += -DDEBUG +ASFLAGS += -DDEBUG export DEBUG endif diff --git a/Pal/src/host/Linux-SGX/enclave_entry.S b/Pal/src/host/Linux-SGX/enclave_entry.S index 6191848f..aa1be260 100644 --- a/Pal/src/host/Linux-SGX/enclave_entry.S +++ b/Pal/src/host/Linux-SGX/enclave_entry.S @@ -254,6 +254,19 @@ enclave_entry: # %rdi, %rsi: (optional) arguments to untrusted code. .Lclear_and_eexit: +#ifdef DEBUG + # Enclave and untrusted stacks are split (segmented). GDB refuses to + # unwind such stacks because it looks like stack frames "jump" back + # and forth. Luckily, GDB special-cases stack frames for a function + # with hardcoded name "__morestack". Declare this dummy function + # to make GDB happy. + + .global __morestack + .type __morestack, @function +__morestack: +#endif + + .cfi_startproc # CFA is away from RBP by ret_addr + saved_rbp + GPR context except RAX .cfi_def_cfa %rbp, SGX_CONTEXT_SIZE - 8 + 16 .cfi_offset %rbp, -16 @@ -280,7 +293,15 @@ enclave_entry: # %rcx is set to AEP by EEXIT xorq %rdx, %rdx # %rsi, %rdi are arguments to the untrusted code + +#ifdef DEBUG +.Lfor_cfa_debug_info: + # Leave %rbp pointing to OCALL function on trusted stack. +#else + # In non-debug mode, clear %rbp to not leak trusted stack address. xorq %rbp, %rbp +#endif + # %rsp points to untrusted stack xorq %r8, %r8 xorq %r9, %r9 @@ -295,6 +316,7 @@ enclave_entry: ENCLU ud2 # We should never get here. + .cfi_endproc # fxsave/xsave area to reset extended state. # @@ -376,6 +398,13 @@ sgx_ocall: movq %gs:SGX_USTACK, %rsp andq $STACK_ALIGN, %rsp +#ifdef DEBUG + # Push %rip of some code inside __morestack() on untrusted stack. + # At sgx_entry(), GDB deduces saved_rip by looking at CFA-8 = %rsp. + leaq .Lfor_cfa_debug_info(%rip), %r8 + pushq %r8 +#endif + movq %gs:SGX_EXIT_TARGET, %rbx jmp .Lclear_and_eexit .cfi_endproc