Browse Source

fixup! [LibOS,Pal] Force intermediate process to wait for child after execve()

Dmitrii Kuvaiskii 4 years ago
parent
commit
c0bc72856a

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

@@ -525,8 +525,8 @@ reopen:
      * and the execve'ed child, but it must still be around until the child finally exits (because
      * its parent in turn may wait on it, e.g., `bash -c ls`) */
     debug(
-        "Temporary process %u exits after emulating execve (by forking new process to replace this"
-        " one); will wait for forked process to exit...\n", cur_process.vmid & 0xFFFF);
+        "Temporary process %u is exiting after emulating execve (by forking new process to replace"
+        " this one); will wait for forked process to exit...\n", cur_process.vmid & 0xFFFF);
     MASTER_LOCK();
     DkProcessExit(PAL_WAIT_FOR_CHILDREN_EXIT);
 

+ 8 - 4
Pal/include/pal/pal.h

@@ -389,10 +389,14 @@ PAL_HANDLE
 DkProcessCreate (PAL_STR uri, PAL_STR * args);
 
 
-/* Magic exit code that instructs the exiting process to wait for its children. Required for a
- * corner case when the parent exec's the child in a new Graphene process: for correctness,
- * the parent cannot immediately exit since it may have a parent that waits on it. We hope that
- * no sane application will pick this magic number as its exit code. */
+/*!
+ * \brief Magic exit code that instructs the exiting process to wait for its children
+ *
+ * Required for a corner case when the parent exec's the child in a new Graphene process: for
+ * correctness, the parent cannot immediately exit since it may have a parent that waits on it.
+ * If an application by coincidence picks this magic number as its exit code, it is changed to
+ * another exit code so as to not confuse the PAL code.
+ */
 #define PAL_WAIT_FOR_CHILDREN_EXIT (1024 * 1024)
 
 noreturn void

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

@@ -26,14 +26,14 @@ static long sgx_ocall_exit(void* pms)
          * be around until the child finally exits (because its parent in turn may wait on it) */
         SGX_DBG(DBG_I, "Temporary process exits after emulating execve, wait for child to exit\n");
 
-        int ret = INLINE_SYSCALL(wait4, 4, /*any child*/-1, /*wstatus=*/NULL, /*options=*/0,
-                                 /*rusage=*/NULL);
+        int wstatus;
+        int ret = INLINE_SYSCALL(wait4, 4, /*any child*/-1, &wstatus, /*options=*/0, /*rusage=*/NULL);
         if (IS_ERR(ret)) {
             /* it's too late to recover from errors, just log it and continue with dying */
             SGX_DBG(DBG_I, "Temporary process waited for child to exit but received error %d\n", ret);
         }
 
-        ms->ms_exitcode = 0;
+        ms->ms_exitcode = wstatus;
     }
 
     if (ms->ms_exitcode != (int) ((uint8_t) ms->ms_exitcode)) {

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

@@ -425,9 +425,9 @@ noreturn void _DkProcessExit (int exitcode)
     if (exitcode == PAL_WAIT_FOR_CHILDREN_EXIT) {
         /* this is a "temporary" process exiting after execve'ing a child process: it must still
          * be around until the child finally exits (because its parent in turn may wait on it) */
-        INLINE_SYSCALL(wait4, 4, /*any child*/-1, /*wstatus=*/NULL, /*options=*/0,
-                       /*rusage=*/NULL);
-        exitcode = 0;
+        int wstatus;
+        INLINE_SYSCALL(wait4, 4, /*any child*/-1, &wstatus, /*options=*/0, /*rusage=*/NULL);
+        exitcode = wstatus;
     }
 
     INLINE_SYSCALL(exit_group, 1, exitcode);