mirror of
https://github.com/clearlinux/graphene.git
synced 2026-09-06 22:01:29 +00:00
[Pal/Linux-SGX] Clear SSA.GPRSGX.EXITINFO after it was used once
Previously, Linux-SGX PAL did not clear SSA.GPRSGX.EXITINFO while in signal handler (which Graphene enters in response to AEX). Note that Graphene first checks trustworthy EXITINFO (filled by SGX HW on AEX) to identify the reason for signal/exception, and only then falls back to possibly malicious `sgx_raise()` argument (filled by Linux kernel and propagated by untrusted PAL). Not clearing EXITINFO led to a subtle racey failure of OpenMP test (and possibly others): main thread sends SIGCONT async signal to child thread, and child thread executes forbidden SYSCALL instruction and gets AEX(SIGILL) at the same time. Now if SIGILL due to SYSCALL arrives first, EXITINFO is filled with SIGILL information. Then SIGCONT is queued on the enclave signal stack, in the same SSA (see `enclave_entry.S:Lsetup_exception_handler`). After SIGILL is correctly handled using the first signal-stack frame, SIGCONT is handled next. However, since EXITINFO was not cleared, SIGCONT's signal-stack frame contains wrong EXITINFO = SIGILL. This confused Graphene: it tried to handle SIGILL instead of SIGCONT. This commit fixes this bug by simply clearing EXITINFO after it was checked once. This works because it is impossible to have two SGX HW exceptions on the same thread at the same time, so we do not lose any vital information by clearing EXITINFO.
This commit is contained in:
committed by
Michał Kowalczyk
parent
941303bb30
commit
1293bc151d
@@ -453,6 +453,11 @@ enclave_entry:
|
||||
subq $8, %rsi
|
||||
movq %rsi, SGX_GPR_RSP(%rbx)
|
||||
|
||||
# clear SSA.GPRSGX.EXITINFO; we used it to identify HW exception (if any),
|
||||
# and a scenario is possible where the same SSA is re-used to handle more
|
||||
# signals that arrive right after this exception, so we must clear state
|
||||
movq $0, SGX_GPR_EXITINFO(%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)
|
||||
|
||||
Reference in New Issue
Block a user