Pārlūkot izejas kodu

Fix error code propagation on SGX (#205), add unit tests for exit code propagation

Don Porter 6 gadi atpakaļ
vecāks
revīzija
5d8c9ac260

+ 3 - 3
LibOS/shim/src/shim_init.c

@@ -62,7 +62,7 @@ void __abort(void) {
 }
 
 void warn (const char *format, ...)
-{ 
+{
     va_list args;
     va_start (args, format);
     __sys_vprintf(format, &args);
@@ -1097,7 +1097,7 @@ static void print_profile_result (PAL_HANDLE hdl, struct shim_profile * root,
     }
     if (total_interval_count) {
         __sys_fprintf(hdl, "                - (%11.11u) total: %u times, %lu msec\n",
-                      total_interval_time, total_interval_count, 
+                      total_interval_time, total_interval_count,
                       total_interval_time / total_interval_count);
     }
 }
@@ -1161,7 +1161,7 @@ int shim_clean (void)
         DkObjectClose(shim_stdio);
 
     shim_stdio = NULL;
-    debug("process %u successfully terminated\n", cur_process.vmid & 0xFFFF);
+    debug("process %u exited with status %d\n", cur_process.vmid & 0xFFFF, cur_process.exit_code);
     master_lock();
     DkProcessExit(cur_process.exit_code);
     return 0;

+ 1 - 0
LibOS/shim/src/sys/shim_exit.c

@@ -133,6 +133,7 @@ int try_process_exit (int error_code, int term_signal)
     struct shim_thread * cur_thread = get_cur_thread();
 
     cur_thread->exit_code = -error_code;
+    cur_process.exit_code = error_code;
     cur_thread->term_signal = term_signal;
 
     if (cur_thread->in_vm)

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 2 - 1
LibOS/shim/test/regression/00_bootstrap.py


+ 9 - 0
LibOS/shim/test/regression/exit.c

@@ -0,0 +1,9 @@
+/* -*- mode:c; c-file-style:"k&r"; c-basic-offset: 4; tab-width:4; indent-tabs-mode:nil; mode:auto-fill; fill-column:78; -*- */
+/* vim: set ts=4 sw=4 et tw=78 fo=cqt wm=0: */
+
+#include <stdio.h>
+
+int main(int argc, const char ** argv, const char ** envp)
+{
+    return 113;
+}

+ 7 - 0
Pal/regression/02_Misc.py

@@ -31,3 +31,10 @@ regression.add_check(name="Hex 2 String Helper Function",
 rv = regression.run_checks()
 if rv: sys.exit(rv)
 
+regression = Regression(loader, "Exit")
+
+regression.add_check(name="Exit Code Propagation",
+    check=lambda res: 112 == res[0].code)
+
+rv = regression.run_checks()
+if rv: sys.exit(rv)

+ 1 - 0
Pal/regression/03_Process.py

@@ -50,3 +50,4 @@ regression.add_check(name="Process Creation without Executable",
 
 rv = regression.run_checks()
 if rv: sys.exit(rv)
+

+ 1 - 0
Pal/regression/05_Process.py

@@ -47,3 +47,4 @@ regression.add_check(name="Process Creation without Executable",
 
 rv = regression.run_checks()
 #if rv: sys.exit(rv)
+

+ 11 - 0
Pal/regression/Exit.c

@@ -0,0 +1,11 @@
+/* -*- mode:c; c-file-style:"k&r"; c-basic-offset: 4; tab-width:4; indent-tabs-mode:nil; mode:auto-fill; fill-column:78; -*- */
+/* vim: set ts=4 sw=4 et tw=78 fo=cqt wm=0: */
+
+#include "pal.h"
+#include "pal_debug.h"
+#include "api.h"
+
+int main (int argc, char ** argv, char ** envp)
+{
+    DkProcessExit(112);
+}

+ 8 - 5
Pal/src/host/Linux-SGX/db_main.c

@@ -130,6 +130,7 @@ void pal_linux_main(const char ** arguments, const char ** environments,
 {
     PAL_HANDLE parent = NULL;
     unsigned long start_time = _DkSystemTimeQuery();
+    int rv;
 
     /* relocate PAL itself */
     pal_map.l_addr = (ElfW(Addr)) sec_info->enclave_addr;
@@ -156,8 +157,10 @@ void pal_linux_main(const char ** arguments, const char ** environments,
 
     /* if there is a parent, create parent handle */
     if (pal_sec.ppid) {
-        if (init_child_process(&parent) < 0)
-            ocall_exit();
+        if ((rv = init_child_process(&parent)) < 0) {
+            SGX_DBG(DBG_E, "Failed to initialize child process: %d\n", rv);
+            ocall_exit(rv);
+        }
     }
 
     linux_state.uid = pal_sec.uid;
@@ -189,9 +192,9 @@ void pal_linux_main(const char ** arguments, const char ** environments,
     root_config->free = free;
 
     const char * errstring = NULL;
-    if (read_config(root_config, loader_filter, &errstring) < 0) {
-        SGX_DBG(DBG_E, "Can't read manifest: %s\n", errstring);
-        ocall_exit();
+    if ((rv = read_config(root_config, loader_filter, &errstring)) < 0) {
+        SGX_DBG(DBG_E, "Can't read manifest: %s, error code %d\n", errstring, rv);
+        ocall_exit(rv);
     }
 
     pal_state.root_config = root_config;

+ 3 - 1
Pal/src/host/Linux-SGX/db_process.c

@@ -326,7 +326,9 @@ void _DkProcessExit (int exitcode)
 #if PRINT_ENCLAVE_STAT
     print_alloced_pages();
 #endif
-    ocall_exit();
+    if (exitcode)
+        SGX_DBG(DBG_I, "DkProcessExit: Returning exit code %d\n", exitcode);
+    ocall_exit(exitcode);
 }
 
 int _DkProcessSandboxCreate (const char * manifest, int flags)

+ 1 - 1
Pal/src/host/Linux-SGX/db_threading.c

@@ -121,7 +121,7 @@ void _DkThreadYieldExecution (void)
 /* _DkThreadExit for internal use: Thread exiting */
 void _DkThreadExit (void)
 {
-    ocall_exit();
+    ocall_exit(0);
 }
 
 int _DkThreadResume (PAL_HANDLE threadHandle)

+ 1 - 1
Pal/src/host/Linux-SGX/enclave_ecalls.c

@@ -55,6 +55,6 @@ int handle_ecall (long ecall_index, void * ecall_args, void * exit_target,
             break;
     }
 
-    ocall_exit();
+    ocall_exit(0);
     return 0;
 }

+ 3 - 2
Pal/src/host/Linux-SGX/enclave_ocalls.c

@@ -64,10 +64,11 @@ int printf(const char * fmt, ...);
         } _ret;                                             \
     })
 
-int ocall_exit(void)
+int ocall_exit(int exitcode)
 {
     int retval = 0;
-    SGX_OCALL(OCALL_EXIT, NULL);
+    int64_t code = exitcode;
+    SGX_OCALL(OCALL_EXIT, (void *) code);
     /* never reach here */
     return retval;
 }

+ 1 - 1
Pal/src/host/Linux-SGX/enclave_ocalls.h

@@ -11,7 +11,7 @@
 #include <linux/socket.h>
 #include <linux/poll.h>
 
-int ocall_exit (void);
+int ocall_exit (int exitcode);
 
 int ocall_print_string (const char * str, unsigned int length);
 

+ 7 - 3
Pal/src/host/Linux-SGX/sgx_enclave.c

@@ -22,10 +22,14 @@
 
 #define ODEBUG(code, ms) do {} while (0)
 
-static int sgx_ocall_exit(void * pms)
+static int sgx_ocall_exit(int rv)
 {
     ODEBUG(OCALL_EXIT, NULL);
-    INLINE_SYSCALL(exit, 1, 0);
+    if (rv != (int) ((uint8_t) rv)) {
+        SGX_DBG(DBG_E, "Saturation error in exit code %d, getting rounded down to %u\n", rv, (uint8_t) rv);
+        rv = 255;
+    }
+    INLINE_SYSCALL(exit, 1, rv);
     return 0;
 }
 
@@ -721,5 +725,5 @@ int ecall_thread_start (void)
 }
 
 void __abort(void) {
-    INLINE_SYSCALL(exit_group, 1, -1); 
+    INLINE_SYSCALL(exit_group, 1, -1);
 }

Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels