Delay clearing owning proc in sys_exec
authorBarret Rhoden <brho@cs.berkeley.edu>
Fri, 30 Sep 2016 20:30:07 +0000 (16:30 -0400)
committerBarret Rhoden <brho@cs.berkeley.edu>
Thu, 6 Oct 2016 19:41:48 +0000 (15:41 -0400)
If we do it before any of the return calls, we could end up returning to
userspace while owning_proc isn't set.  I think the rest of the kernel is
able to handle this, but there's no sense messing around.  The old comment
makes it sound like we can block in that state too, which is probably true,
but returning by anything other than the error path ways seems like a bad
idea.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/src/syscall.c

index cbd9ba5..6b51cdf 100644 (file)
@@ -953,15 +953,6 @@ static int sys_exec(struct proc *p, char *path, size_t path_l,
        /* Preemptively copy out the cur_ctx, in case we fail later (easier on
         * cur_ctx if we do this now) */
        copy_current_ctx_to(&p->scp_ctx);
-       /* Clear the current_ctx.  We won't be returning the 'normal' way.  Even if
-        * we want to return with an error, we need to go back differently in case
-        * we succeed.  This needs to be done before we could possibly block, but
-        * unfortunately happens before the point of no return.
-        *
-        * Note that we will 'hard block' if we block at all.  We can't return to
-        * userspace and then asynchronously finish the exec later. */
-       clear_owning_proc(core_id());
-
        /* Check the size of the argenv array, error out if too large. */
        if ((argenv_l < sizeof(struct argenv)) || (argenv_l > ARG_MAX)) {
                set_error(EINVAL, "The argenv array has an invalid size: %lu\n",
@@ -989,6 +980,14 @@ static int sys_exec(struct proc *p, char *path, size_t path_l,
        /* This could block: */
        /* TODO: 9ns support */
        program = do_file_open(t_path, O_READ, 0);
+       /* Clear the current_ctx.  We won't be returning the 'normal' way.  Even if
+        * we want to return with an error, we need to go back differently in case
+        * we succeed.  This needs to be done before we could possibly block, but
+        * unfortunately happens before the point of no return.
+        *
+        * Note that we will 'hard block' if we block at all.  We can't return to
+        * userspace and then asynchronously finish the exec later. */
+       clear_owning_proc(core_id());
        if (!program)
                goto early_error;
        if (!is_valid_elf(program)) {