> On Nov 6, 2018, at 11:22 AM, Dave Hansen <dave.hansen@xxxxxxxxx> wrote: > >> On 11/6/18 11:02 AM, Andy Lutomirski wrote: >>> On Tue, Nov 6, 2018 at 10:41 AM Dave Hansen <dave.hansen@xxxxxxxxx> wrote: >>> >>>> On 11/6/18 10:20 AM, Andy Lutomirski wrote: >>>> I almost feel like the right solution is to call into SGX on its own >>>> private stack or maybe even its own private address space. >>> >>> Yeah, I had the same gut feeling. Couldn't the debugger even treat the >>> enclave like its own "thread" with its own stack and its own set of >>> registers and context? That seems like a much more workable model than >>> trying to weave it together with the EENTER context. >> >> So maybe the API should be, roughly >> >> sgx_exit_reason_t sgx_enter_enclave(pointer_to_enclave, struct >> host_state *state); >> sgx_exit_reason_t sgx_resume_enclave(same args); >> >> where host_state is something like: >> >> struct host_state { >> unsigned long bp, sp, ax, bx, cx, dx, si, di; >> }; >> >> and the values in host_state explicitly have nothing to do with the >> actual host registers. So, if you want to use the outcall mechanism, >> you'd allocate some memory, point sp to that memory, call >> sgx_enter_enclave(), and then read that memory to do the outcall. > > Ah, so instead of the enclave rudely "hijacking" the EENTER context, we > have it nicely return and nicely _hint_ to the calling context what it > would like to do. Then, the EENTER context can make a controlled > transition over to the requested context. Exactly. And existing enclaves keep working — their rudeness is just magically translated into a hint! > >> Actually implementing this would be distinctly nontrivial, and would >> almost certainly need some degree of kernel help to avoid an explosion >> when a signal gets delivered while we have host_state.sp loaded into >> the actual SP register. Maybe rseq could help with this? > > As long as the memory pointed to by host_state.sp is valid and can hold > the signal frame (grows down without clobbering anything), what goes > boom? The signal handling would push a signal frame and call the > handler. It would have a shallow-looking stack, but the handler could > just do its normal business and return from the signal where the frame > would get popped and continue with %rsp=host_state.sp, blissfully > unaware of the signal ever having happened. True, but what if we have a nasty enclave that writes to memory just below SP *before* decrementing SP? I suspect that rseq really can be used for this with only minimal-ish modifications. Or we could stick this in the vDSO with some appropriate fixups in the kernel.