Quellcode durchsuchen

[Pal/Linux-SGX] Disallow nested signals at host-OS level

This commit ensures that TCS.CSSA == 1 while entering enclave
execution to handle a signal from host OS (recall that CSSA == 0 is for
normal enclave execution and CSSA == 1 is for signal-handling
enclave preparation). This effectively disallows nested signal handling
from a malicious OS. Disallowing nested signals simplifies our code.
Benign OS is prevented from nesting by blocking async signals during
signal handling.

Note that currently enclaves are always run with TCS.NSSA == 2, and SGX
hardware will disallow entering the enclave if TCS.CSSA > 1. Thus, this
commit serves as an assertion in case NSSA limit is changed in future.
Isaku Yamahata vor 5 Jahren
Ursprung
Commit
5b3b69332a
2 geänderte Dateien mit 18 neuen und 0 gelöschten Zeilen
  1. 14 0
      Pal/src/host/Linux-SGX/enclave_entry.S
  2. 4 0
      Pal/src/host/Linux-SGX/sgx_exception.c

+ 14 - 0
Pal/src/host/Linux-SGX/enclave_entry.S

@@ -102,6 +102,20 @@ enclave_entry:
 	# PAL convention:
 	# RDI - external event
 
+	# Nested exceptions at the host-OS level are disallowed:
+	# - Synchronous exceptions are assumed to never happen during
+	#   handle_resume;
+	# - Asynchronous signals are not nested by benign host OS because
+	#   we mask asynchronous signals on signal handler.
+	# If malicious host OS injects a nested signal, CSSA != 1 and we
+	# fail execution.
+	# This FAIL_LOOP is assertion only because
+	# currently this is also enforced by EENTER because NSSA == 2
+	cmpq $1, %rax
+	je 1f
+	FAIL_LOOP
+1:
+
 	# get some information from GPR
 	movq %gs:SGX_GPR, %rbx
 

+ 4 - 0
Pal/src/host/Linux-SGX/sgx_exception.c

@@ -91,7 +91,11 @@ int set_sighandler (int * sigs, int nsig, void * handler)
     action.sa_restorer = __restore_rt;
 #endif
 
+    /* Disallow nested asynchronous signals during enclave exception handling.
+     */
     __sigemptyset((__sigset_t *) &action.sa_mask);
+    __sigaddset((__sigset_t *) &action.sa_mask, SIGTERM);
+    __sigaddset((__sigset_t *) &action.sa_mask, SIGINT);
     __sigaddset((__sigset_t *) &action.sa_mask, SIGCONT);
 
     for (int i = 0 ; i < nsig ; i++) {