aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/fork.c
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2011-06-17 10:50:38 -0400
committerOleg Nesterov <oleg@redhat.com>2011-06-22 13:26:29 -0400
commit4b9d33e6d83cc05a8005a8f9a8b9677fa0f53626 (patch)
tree250b740d22f9604326ecfd769dd2f74d60187a19 /kernel/fork.c
parenta288eecce5253cc1565d400a52b9b476a157e040 (diff)
ptrace: kill clone/exec tracehooks
At this point, tracehooks aren't useful to mainline kernel and mostly just add an extra layer of obfuscation. Although they have comments, without actual in-kernel users, it is difficult to tell what are their assumptions and they're actually trying to achieve. To mainline kernel, they just aren't worth keeping around. This patch kills the following clone and exec related tracehooks. tracehook_prepare_clone() tracehook_finish_clone() tracehook_report_clone() tracehook_report_clone_complete() tracehook_unsafe_exec() The changes are mostly trivial - logic is moved to the caller and comments are merged and adjusted appropriately. The only exception is in check_unsafe_exec() where LSM_UNSAFE_PTRACE* are OR'd to bprm->unsafe instead of setting it, which produces the same result as the field is always zero on entry. It also tests p->ptrace instead of (p->ptrace & PT_PTRACED) for consistency, which also gives the same result. This doesn't introduce any behavior change. Signed-off-by: Tejun Heo <tj@kernel.org> Cc: Christoph Hellwig <hch@infradead.org> Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Diffstat (limited to 'kernel/fork.c')
-rw-r--r--kernel/fork.c41
1 files changed, 32 insertions, 9 deletions
diff --git a/kernel/fork.c b/kernel/fork.c
index d4f0dff9d617..3c72a5b321a7 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1340,7 +1340,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
1340 } 1340 }
1341 1341
1342 if (likely(p->pid)) { 1342 if (likely(p->pid)) {
1343 tracehook_finish_clone(p, clone_flags, trace); 1343 ptrace_init_task(p, (clone_flags & CLONE_PTRACE) || trace);
1344 1344
1345 if (thread_group_leader(p)) { 1345 if (thread_group_leader(p)) {
1346 if (is_child_reaper(pid)) 1346 if (is_child_reaper(pid))
@@ -1481,10 +1481,22 @@ long do_fork(unsigned long clone_flags,
1481 } 1481 }
1482 1482
1483 /* 1483 /*
1484 * When called from kernel_thread, don't do user tracing stuff. 1484 * Determine whether and which event to report to ptracer. When
1485 * called from kernel_thread or CLONE_UNTRACED is explicitly
1486 * requested, no event is reported; otherwise, report if the event
1487 * for the type of forking is enabled.
1485 */ 1488 */
1486 if (likely(user_mode(regs))) 1489 if (likely(user_mode(regs)) && !(clone_flags & CLONE_UNTRACED)) {
1487 trace = tracehook_prepare_clone(clone_flags); 1490 if (clone_flags & CLONE_VFORK)
1491 trace = PTRACE_EVENT_VFORK;
1492 else if ((clone_flags & CSIGNAL) != SIGCHLD)
1493 trace = PTRACE_EVENT_CLONE;
1494 else
1495 trace = PTRACE_EVENT_FORK;
1496
1497 if (likely(!ptrace_event_enabled(current, trace)))
1498 trace = 0;
1499 }
1488 1500
1489 p = copy_process(clone_flags, stack_start, regs, stack_size, 1501 p = copy_process(clone_flags, stack_start, regs, stack_size,
1490 child_tidptr, NULL, trace); 1502 child_tidptr, NULL, trace);
@@ -1508,20 +1520,31 @@ long do_fork(unsigned long clone_flags,
1508 } 1520 }
1509 1521
1510 audit_finish_fork(p); 1522 audit_finish_fork(p);
1511 tracehook_report_clone(regs, clone_flags, nr, p); 1523
1524 /*
1525 * Child is ready but hasn't started running yet. Queue
1526 * SIGSTOP if it's gonna be ptraced - it doesn't matter who
1527 * attached/attaching to this task, the pending SIGSTOP is
1528 * right in any case.
1529 */
1530 if (unlikely(p->ptrace)) {
1531 sigaddset(&p->pending.signal, SIGSTOP);
1532 set_tsk_thread_flag(p, TIF_SIGPENDING);
1533 }
1512 1534
1513 /* 1535 /*
1514 * We set PF_STARTING at creation in case tracing wants to 1536 * We set PF_STARTING at creation in case tracing wants to
1515 * use this to distinguish a fully live task from one that 1537 * use this to distinguish a fully live task from one that
1516 * hasn't gotten to tracehook_report_clone() yet. Now we 1538 * hasn't finished SIGSTOP raising yet. Now we clear it
1517 * clear it and set the child going. 1539 * and set the child going.
1518 */ 1540 */
1519 p->flags &= ~PF_STARTING; 1541 p->flags &= ~PF_STARTING;
1520 1542
1521 wake_up_new_task(p); 1543 wake_up_new_task(p);
1522 1544
1523 tracehook_report_clone_complete(trace, regs, 1545 /* forking complete and child started to run, tell ptracer */
1524 clone_flags, nr, p); 1546 if (unlikely(trace))
1547 ptrace_event(trace, nr);
1525 1548
1526 if (clone_flags & CLONE_VFORK) { 1549 if (clone_flags & CLONE_VFORK) {
1527 freezer_do_not_count(); 1550 freezer_do_not_count();