aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorOleg Nesterov <oleg@redhat.com>2013-09-11 17:24:38 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-09-11 18:59:03 -0400
commit5d1baf3b63bfc8c709dc44df85ff1475c7ef489d (patch)
treec22cad96687d70a544674f7eb823026aecf4ceeb /fs
parent96d0df79f2644fc823f26c06491e182d87a90c2a (diff)
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>
Diffstat (limited to 'fs')
-rw-r--r--fs/exec.c36
1 files changed, 22 insertions, 14 deletions
diff --git a/fs/exec.c b/fs/exec.c
index 2d1e52a58fe9..4d95b4709ea0 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1373,7 +1373,6 @@ int search_binary_handler(struct linux_binprm *bprm)
1373 unsigned int depth = bprm->recursion_depth; 1373 unsigned int depth = bprm->recursion_depth;
1374 int try,retval; 1374 int try,retval;
1375 struct linux_binfmt *fmt; 1375 struct linux_binfmt *fmt;
1376 pid_t old_pid, old_vpid;
1377 1376
1378 /* This allows 4 levels of binfmt rewrites before failing hard. */ 1377 /* This allows 4 levels of binfmt rewrites before failing hard. */
1379 if (depth > 5) 1378 if (depth > 5)
@@ -1387,12 +1386,6 @@ int search_binary_handler(struct linux_binprm *bprm)
1387 if (retval) 1386 if (retval)
1388 return retval; 1387 return retval;
1389 1388
1390 /* Need to fetch pid before load_binary changes it */
1391 old_pid = current->pid;
1392 rcu_read_lock();
1393 old_vpid = task_pid_nr_ns(current, task_active_pid_ns(current->parent));
1394 rcu_read_unlock();
1395
1396 retval = -ENOENT; 1389 retval = -ENOENT;
1397 for (try=0; try<2; try++) { 1390 for (try=0; try<2; try++) {
1398 read_lock(&binfmt_lock); 1391 read_lock(&binfmt_lock);
@@ -1407,16 +1400,11 @@ int search_binary_handler(struct linux_binprm *bprm)
1407 retval = fn(bprm); 1400 retval = fn(bprm);
1408 bprm->recursion_depth = depth; 1401 bprm->recursion_depth = depth;
1409 if (retval >= 0) { 1402 if (retval >= 0) {
1410 if (depth == 0) {
1411 trace_sched_process_exec(current, old_pid, bprm);
1412 ptrace_event(PTRACE_EVENT_EXEC, old_vpid);
1413 }
1414 put_binfmt(fmt); 1403 put_binfmt(fmt);
1415 allow_write_access(bprm->file); 1404 allow_write_access(bprm->file);
1416 if (bprm->file) 1405 if (bprm->file)
1417 fput(bprm->file); 1406 fput(bprm->file);
1418 bprm->file = NULL; 1407 bprm->file = NULL;
1419 current->did_exec = 1;
1420 proc_exec_connector(current); 1408 proc_exec_connector(current);
1421 return retval; 1409 return retval;
1422 } 1410 }
@@ -1450,9 +1438,29 @@ int search_binary_handler(struct linux_binprm *bprm)
1450 } 1438 }
1451 return retval; 1439 return retval;
1452} 1440}
1453
1454EXPORT_SYMBOL(search_binary_handler); 1441EXPORT_SYMBOL(search_binary_handler);
1455 1442
1443static int exec_binprm(struct linux_binprm *bprm)
1444{
1445 pid_t old_pid, old_vpid;
1446 int ret;
1447
1448 /* Need to fetch pid before load_binary changes it */
1449 old_pid = current->pid;
1450 rcu_read_lock();
1451 old_vpid = task_pid_nr_ns(current, task_active_pid_ns(current->parent));
1452 rcu_read_unlock();
1453
1454 ret = search_binary_handler(bprm);
1455 if (ret >= 0) {
1456 trace_sched_process_exec(current, old_pid, bprm);
1457 ptrace_event(PTRACE_EVENT_EXEC, old_vpid);
1458 current->did_exec = 1;
1459 }
1460
1461 return ret;
1462}
1463
1456/* 1464/*
1457 * sys_execve() executes a new program. 1465 * sys_execve() executes a new program.
1458 */ 1466 */
@@ -1541,7 +1549,7 @@ static int do_execve_common(const char *filename,
1541 if (retval < 0) 1549 if (retval < 0)
1542 goto out; 1550 goto out;
1543 1551
1544 retval = search_binary_handler(bprm); 1552 retval = exec_binprm(bprm);
1545 if (retval < 0) 1553 if (retval < 0)
1546 goto out; 1554 goto out;
1547 1555