Browse Source

[LibOS] Return proper error code on initialization fail

Rafał Wojdyła 5 years ago
parent
commit
aba21c360e

+ 4 - 3
LibOS/shim/include/shim_internal.h

@@ -145,7 +145,7 @@ static inline PAL_HANDLE __open_shim_stdio (void)
     return shim_stdio;
 }
 
-int shim_terminate (void);
+int shim_terminate (int err);
 
 /* assertions */
 #define USE_PAUSE       0
@@ -163,7 +163,7 @@ static inline void do_pause (void);
     do {                                                                    \
         __sys_printf("bug() " __FILE__ ":%d\n", __LINE__);                  \
         pause();                                                            \
-        shim_terminate();                                                   \
+        shim_terminate(-ENOTRECOVERABLE);                                   \
     } while (0)
 
 #if USE_ASSERT == 1
@@ -749,7 +749,8 @@ static inline bool memory_migrated(void * mem)
 extern void * __load_address, * __load_address_end;
 extern void * __code_address, * __code_address_end;
 
-int shim_clean (void);
+/* cleanup and terminate process, preserve exit code if err == 0 */
+int shim_clean (int err);
 
 unsigned long parse_int (const char * str);
 

+ 1 - 1
LibOS/shim/src/ipc/shim_ipc_helper.c

@@ -1034,7 +1034,7 @@ end:
     barrier();
     if (ipc_helper_state == HELPER_HANDEDOVER) {
         debug("ipc helper thread is the last thread, process exiting\n");
-        shim_terminate(); // Same as shim_clean(), but this is the official termination function
+        shim_terminate(0); // Same as shim_clean(), but this is the official termination function
     }
 
     lock(ipc_helper_lock);

+ 10 - 7
LibOS/shim/src/shim_init.c

@@ -59,7 +59,7 @@ static void handle_failure (PAL_PTR event, PAL_NUM arg, PAL_CONTEXT * context)
 
 void __abort(void) {
     pause();
-    shim_terminate();
+    shim_terminate(-ENOTRECOVERABLE);
 }
 
 void warn (const char *format, ...)
@@ -671,7 +671,7 @@ DEFINE_PROFILE_INTERVAL(init_signal,                init);
         int _err = CALL_INIT(func, ##__VA_ARGS__);                      \
         if (_err < 0) {                                                 \
             sys_printf("shim_init() in " #func " (%d)\n", _err);        \
-            shim_terminate();                                           \
+            shim_terminate(_err);                                       \
         }                                                               \
         SAVE_PROFILE_INTERVAL(func);                                    \
     } while (0)
@@ -1121,18 +1121,19 @@ static void print_profile_result (PAL_HANDLE hdl, struct shim_profile * root,
 
 static struct atomic_int in_terminate = { .counter = 0, };
 
-int shim_terminate (void)
+int shim_terminate (int err)
 {
-    debug("teminating the whole process\n");
+    debug("teminating the whole process (%d)\n", err);
 
     /* do last clean-up of the process */
-    shim_clean();
+    shim_clean(err);
 
-    DkProcessExit(0);
+    DkProcessExit(err);
     return 0;
 }
 
-int shim_clean (void)
+/* cleanup and terminate process, preserve exit code if err == 0 */
+int shim_clean (int err)
 {
     /* preventing multiple cleanup, this is mostly caused by
        assertion in shim_clean */
@@ -1140,6 +1141,8 @@ int shim_clean (void)
     if (atomic_read(&in_terminate) > 1)
         return 0;
 
+    if (err != 0)
+        cur_process.exit_code = err;
     store_all_msg_persist();
 
 #ifdef PROFILE

+ 1 - 1
LibOS/shim/src/sys/shim_exec.c

@@ -182,7 +182,7 @@ retry_dump_vmas:
     SAVE_PROFILE_INTERVAL(unmap_all_vmas_for_exec);
 
     if ((ret = load_elf_object(cur_thread->exec, NULL, 0)) < 0)
-        shim_terminate();
+        shim_terminate(ret);
 
     init_brk_from_executable(cur_thread->exec);
     load_elf_interp(cur_thread->exec);

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

@@ -159,7 +159,7 @@ int try_process_exit (int error_code, int term_signal)
          */
         put_thread(ipc_thread); /* free resources of the thread */
     if (!ret)
-        shim_clean();
+        shim_clean(ret);
     else
         DkThreadExit();
 

+ 10 - 0
LibOS/shim/test/regression/00_bootstrap.py

@@ -41,6 +41,7 @@ regression.add_check(name="Shared Object",
 rv = regression.run_checks()
 if rv: sys.exit(rv)
 
+# Exit test
 regression = Regression(loader, "exit")
 
 regression.add_check(name="Exit Code Propagation",
@@ -48,3 +49,12 @@ regression.add_check(name="Exit Code Propagation",
 
 rv = regression.run_checks()
 if rv: sys.exit(rv)
+
+# Early abort test
+regression = Regression(loader, "init_fail")
+
+regression.add_check(name="Early abort",
+    check=lambda res: res[0].code != 42 and res[0].code != 0)
+
+rv = regression.run_checks()
+if rv: sys.exit(rv)

+ 7 - 0
LibOS/shim/test/regression/init_fail.c

@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int main()
+{
+    printf("Hello world\n");
+    return 42;
+}

+ 16 - 0
LibOS/shim/test/regression/init_fail.manifest.template

@@ -0,0 +1,16 @@
+loader.preload = file:$(SHIMPATH)
+loader.env.LD_LIBRARY_PATH = /lib
+loader.debug_type = none
+
+fs.mount.lib.type = chroot
+fs.mount.lib.path = /lib
+fs.mount.lib.uri = file:$(LIBCDIR)
+
+# purposefully force mount failure to cause early shim abort
+fs.mount.test.type = chroot
+fs.mount.test.path = /test
+fs.mount.test.uri = file:I_DONT_EXIST
+
+sgx.trusted_files.ld = file:$(LIBCDIR)/ld-linux-x86-64.so.2
+sgx.trusted_files.libc = file:$(LIBCDIR)/libc.so.6
+