diff options
author | Oleg Nesterov <oleg@redhat.com> | 2014-01-23 18:55:51 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-01-23 19:37:02 -0500 |
commit | 63e46b95e9eae1161832bf45cb40bbad37bfb182 (patch) | |
tree | 642f1ba4567fabd0358a45d77dc653ab98adac14 /fs/exec.c | |
parent | 9e00cdb091b008cb3c78192651180896de412a63 (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.c | 20 |
1 files changed, 5 insertions, 15 deletions
@@ -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(¤t->signal->cred_guard_mutex); | 1170 | mutex_unlock(¤t->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 | ||
1542 | out_file: | ||
1543 | if (bprm->file) { | ||
1544 | allow_write_access(bprm->file); | ||
1545 | fput(bprm->file); | ||
1546 | } | ||
1547 | |||
1548 | out_unmark: | 1538 | out_unmark: |
1549 | current->fs->in_exec = 0; | 1539 | current->fs->in_exec = 0; |
1550 | current->in_execve = 0; | 1540 | current->in_execve = 0; |