aboutsummaryrefslogtreecommitdiffstats
path: root/fs/exec.c
diff options
context:
space:
mode:
authorOleg Nesterov <oleg@redhat.com>2014-01-23 18:55:51 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-01-23 19:37:02 -0500
commit63e46b95e9eae1161832bf45cb40bbad37bfb182 (patch)
tree642f1ba4567fabd0358a45d77dc653ab98adac14 /fs/exec.c
parent9e00cdb091b008cb3c78192651180896de412a63 (diff)
exec: move the final allow_write_access/fput into free_bprm()
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>
Diffstat (limited to 'fs/exec.c')
-rw-r--r--fs/exec.c20
1 files changed, 5 insertions, 15 deletions
diff --git a/fs/exec.c b/fs/exec.c
index 389fe7b0ba14..f860866e04ba 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1138,9 +1138,7 @@ void setup_new_exec(struct linux_binprm * bprm)
1138 1138
1139 /* An exec changes our domain. We are no longer part of the thread 1139 /* An exec changes our domain. We are no longer part of the thread
1140 group */ 1140 group */
1141
1142 current->self_exec_id++; 1141 current->self_exec_id++;
1143
1144 flush_signal_handlers(current, 0); 1142 flush_signal_handlers(current, 0);
1145 do_close_on_exec(current->files); 1143 do_close_on_exec(current->files);
1146} 1144}
@@ -1172,6 +1170,10 @@ void free_bprm(struct linux_binprm *bprm)
1172 mutex_unlock(&current->signal->cred_guard_mutex); 1170 mutex_unlock(&current->signal->cred_guard_mutex);
1173 abort_creds(bprm->cred); 1171 abort_creds(bprm->cred);
1174 } 1172 }
1173 if (bprm->file) {
1174 allow_write_access(bprm->file);
1175 fput(bprm->file);
1176 }
1175 /* If a binfmt changed the interp, free it. */ 1177 /* If a binfmt changed the interp, free it. */
1176 if (bprm->interp != bprm->filename) 1178 if (bprm->interp != bprm->filename)
1177 kfree(bprm->interp); 1179 kfree(bprm->interp);
@@ -1424,12 +1426,6 @@ static int exec_binprm(struct linux_binprm *bprm)
1424 ptrace_event(PTRACE_EVENT_EXEC, old_vpid); 1426 ptrace_event(PTRACE_EVENT_EXEC, old_vpid);
1425 current->did_exec = 1; 1427 current->did_exec = 1;
1426 proc_exec_connector(current); 1428 proc_exec_connector(current);
1427
1428 if (bprm->file) {
1429 allow_write_access(bprm->file);
1430 fput(bprm->file);
1431 bprm->file = NULL; /* to catch use-after-free */
1432 }
1433 } 1429 }
1434 1430
1435 return ret; 1431 return ret;
@@ -1492,7 +1488,7 @@ static int do_execve_common(const char *filename,
1492 1488
1493 retval = bprm_mm_init(bprm); 1489 retval = bprm_mm_init(bprm);
1494 if (retval) 1490 if (retval)
1495 goto out_file; 1491 goto out_unmark;
1496 1492
1497 bprm->argc = count(argv, MAX_ARG_STRINGS); 1493 bprm->argc = count(argv, MAX_ARG_STRINGS);
1498 if ((retval = bprm->argc) < 0) 1494 if ((retval = bprm->argc) < 0)
@@ -1539,12 +1535,6 @@ out:
1539 mmput(bprm->mm); 1535 mmput(bprm->mm);
1540 } 1536 }
1541 1537
1542out_file:
1543 if (bprm->file) {
1544 allow_write_access(bprm->file);
1545 fput(bprm->file);
1546 }
1547
1548out_unmark: 1538out_unmark:
1549 current->fs->in_exec = 0; 1539 current->fs->in_exec = 0;
1550 current->in_execve = 0; 1540 current->in_execve = 0;