exec: introduce exec_binprm() for "depth == 0" code
task_pid_nr_ns() and trace/ptrace code in the middle of the recursive search_binary_handler() looks confusing and imho annoying. We only need this code if "depth == 0", lets add a simple helper which calls search_binary_handler() and does trace_sched_process_exec() + ptrace_event(). The patch also moves the setting of task->did_exec, we need to do this only once. Note: we can kill either task->did_exec or PF_FORKNOEXEC. Signed-off-by: Oleg Nesterov <oleg@redhat.com> Acked-by: Kees Cook <keescook@chromium.org> Cc: Al Viro <viro@ZenIV.linux.org.uk> Cc: Evgeniy Polyakov <zbr@ioremap.net> Cc: Zach Levis <zml@linux.vnet.ibm.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
96d0df79f2
commit
5d1baf3b63
1 changed files with 22 additions and 14 deletions
36
fs/exec.c
36
fs/exec.c
|
@ -1373,7 +1373,6 @@ int search_binary_handler(struct linux_binprm *bprm)
|
|||
unsigned int depth = bprm->recursion_depth;
|
||||
int try,retval;
|
||||
struct linux_binfmt *fmt;
|
||||
pid_t old_pid, old_vpid;
|
||||
|
||||
/* This allows 4 levels of binfmt rewrites before failing hard. */
|
||||
if (depth > 5)
|
||||
|
@ -1387,12 +1386,6 @@ int search_binary_handler(struct linux_binprm *bprm)
|
|||
if (retval)
|
||||
return retval;
|
||||
|
||||
/* Need to fetch pid before load_binary changes it */
|
||||
old_pid = current->pid;
|
||||
rcu_read_lock();
|
||||
old_vpid = task_pid_nr_ns(current, task_active_pid_ns(current->parent));
|
||||
rcu_read_unlock();
|
||||
|
||||
retval = -ENOENT;
|
||||
for (try=0; try<2; try++) {
|
||||
read_lock(&binfmt_lock);
|
||||
|
@ -1407,16 +1400,11 @@ int search_binary_handler(struct linux_binprm *bprm)
|
|||
retval = fn(bprm);
|
||||
bprm->recursion_depth = depth;
|
||||
if (retval >= 0) {
|
||||
if (depth == 0) {
|
||||
trace_sched_process_exec(current, old_pid, bprm);
|
||||
ptrace_event(PTRACE_EVENT_EXEC, old_vpid);
|
||||
}
|
||||
put_binfmt(fmt);
|
||||
allow_write_access(bprm->file);
|
||||
if (bprm->file)
|
||||
fput(bprm->file);
|
||||
bprm->file = NULL;
|
||||
current->did_exec = 1;
|
||||
proc_exec_connector(current);
|
||||
return retval;
|
||||
}
|
||||
|
@ -1450,9 +1438,29 @@ int search_binary_handler(struct linux_binprm *bprm)
|
|||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(search_binary_handler);
|
||||
|
||||
static int exec_binprm(struct linux_binprm *bprm)
|
||||
{
|
||||
pid_t old_pid, old_vpid;
|
||||
int ret;
|
||||
|
||||
/* Need to fetch pid before load_binary changes it */
|
||||
old_pid = current->pid;
|
||||
rcu_read_lock();
|
||||
old_vpid = task_pid_nr_ns(current, task_active_pid_ns(current->parent));
|
||||
rcu_read_unlock();
|
||||
|
||||
ret = search_binary_handler(bprm);
|
||||
if (ret >= 0) {
|
||||
trace_sched_process_exec(current, old_pid, bprm);
|
||||
ptrace_event(PTRACE_EVENT_EXEC, old_vpid);
|
||||
current->did_exec = 1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* sys_execve() executes a new program.
|
||||
*/
|
||||
|
@ -1541,7 +1549,7 @@ static int do_execve_common(const char *filename,
|
|||
if (retval < 0)
|
||||
goto out;
|
||||
|
||||
retval = search_binary_handler(bprm);
|
||||
retval = exec_binprm(bprm);
|
||||
if (retval < 0)
|
||||
goto out;
|
||||
|
||||
|
|
Loading…
Reference in a new issue