OSDN Git Service

exec: move the final allow_write_access/fput into free_bprm()
authorOleg Nesterov <oleg@redhat.com>
Thu, 23 Jan 2014 23:55:51 +0000 (15:55 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 24 Jan 2014 00:37:02 +0000 (16:37 -0800)
Both success/failure paths cleanup bprm->file, we can move this
code into free_bprm() to simlify and cleanup this logic.

Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Acked-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Acked-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
fs/exec.c

index 389fe7b..f860866 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1138,9 +1138,7 @@ void setup_new_exec(struct linux_binprm * bprm)
 
        /* An exec changes our domain. We are no longer part of the thread
           group */
-
        current->self_exec_id++;
-                       
        flush_signal_handlers(current, 0);
        do_close_on_exec(current->files);
 }
@@ -1172,6 +1170,10 @@ void free_bprm(struct linux_binprm *bprm)
                mutex_unlock(&current->signal->cred_guard_mutex);
                abort_creds(bprm->cred);
        }
+       if (bprm->file) {
+               allow_write_access(bprm->file);
+               fput(bprm->file);
+       }
        /* If a binfmt changed the interp, free it. */
        if (bprm->interp != bprm->filename)
                kfree(bprm->interp);
@@ -1424,12 +1426,6 @@ static int exec_binprm(struct linux_binprm *bprm)
                ptrace_event(PTRACE_EVENT_EXEC, old_vpid);
                current->did_exec = 1;
                proc_exec_connector(current);
-
-               if (bprm->file) {
-                       allow_write_access(bprm->file);
-                       fput(bprm->file);
-                       bprm->file = NULL; /* to catch use-after-free */
-               }
        }
 
        return ret;
@@ -1492,7 +1488,7 @@ static int do_execve_common(const char *filename,
 
        retval = bprm_mm_init(bprm);
        if (retval)
-               goto out_file;
+               goto out_unmark;
 
        bprm->argc = count(argv, MAX_ARG_STRINGS);
        if ((retval = bprm->argc) < 0)
@@ -1539,12 +1535,6 @@ out:
                mmput(bprm->mm);
        }
 
-out_file:
-       if (bprm->file) {
-               allow_write_access(bprm->file);
-               fput(bprm->file);
-       }
-
 out_unmark:
        current->fs->in_exec = 0;
        current->in_execve = 0;