History

ptrace: kill trivial 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 trivial tracehooks. * Ones testing whether task is ptraced. Replace with ->ptrace test. tracehook_expect_breakpoints() tracehook_consider_ignored_signal() tracehook_consider_fatal_signal() * ptrace_event() wrappers. Call directly. tracehook_report_exec() tracehook_report_exit() tracehook_report_vfork_done() * ptrace_release_task() wrapper. Call directly. tracehook_finish_release_task() * noop tracehook_prepare_release_task() tracehook_report_death() This doesn't introduce any behavior change.

Tejun Heo committed 15 years ago

Commit a288eec1 parent f3c04b97 files · +11 −171Browse files

Unified · Split

7 files
  1. arch/s390/kernel/traps.c +2 −2
  2. fs/exec.c +1 −1
  3. include/linux/tracehook.h +0 −156
  4. kernel/exit.c +2 −5
  5. kernel/fork.c +1 −1
  6. kernel/signal.c +4 −4
  7. mm/nommu.c +1 −2
arch/s390/kernel/traps.c+2−2
@@ -331,7 +331,7 @@ void __kprobes do_per_trap(struct pt_regs *regs) · 330 unmodified lines
331331 {
332332 if (notify_die(DIE_SSTEP, "sstep", regs, 0, 0, SIGTRAP) == NOTIFY_STOP)
333333 return;
334− if (tracehook_consider_fatal_signal(current, SIGTRAP))
334+ if (current->ptrace)
335335 force_sig(SIGTRAP, current);
336336 }
337337
@@ -425,7 +425,7 @@ static void __kprobes illegal_op(struct pt_regs *regs, long pgm_int_code, · 87 unmodified lines
425425 if (get_user(*((__u16 *) opcode), (__u16 __user *) location))
426426 return;
427427 if (*((__u16 *) opcode) == S390_BREAKPOINT_U16) {
428− if (tracehook_consider_fatal_signal(current, SIGTRAP))
428+ if (current->ptrace)
429429 force_sig(SIGTRAP, current);
430430 else
431431 signal = SIGILL;
fs/exec.c+1−1
@@ -1384,7 +1384,7 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs) · 1383 unmodified lines
13841384 bprm->recursion_depth = depth;
13851385 if (retval >= 0) {
13861386 if (depth == 0)
1387− tracehook_report_exec(fmt, bprm, regs);
1387+ ptrace_event(PTRACE_EVENT_EXEC, 0);
13881388 put_binfmt(fmt);
13891389 allow_write_access(bprm->file);
13901390 if (bprm->file)
include/linux/tracehook.h+0−156
@@ -51,21 +51,6 @@ · 50 unmodified lines
5151 #include <linux/security.h>
5252 struct linux_binprm;
5353
54−/**
55− * tracehook_expect_breakpoints - guess if task memory might be touched
56− * @task: current task, making a new mapping
57− *
58− * Return nonzero if @task is expected to want breakpoint insertion in
59− * its memory at some point. A zero return is no guarantee it won't
60− * be done, but this is a hint that it's known to be likely.
61− *
62− * May be called with @task->mm->mmap_sem held for writing.
63− */
64−static inline int tracehook_expect_breakpoints(struct task_struct *task)
65−{
66− return (task->ptrace & PT_PTRACED) != 0;
67−}
68−
6954 /*
7055 * ptrace report for syscall entry and exit looks identical.
7156 */
@@ -183,42 +168,6 @@ static inline struct task_struct *tracehook_tracer_task(struct task_struct *tsk) · 111 unmodified lines
183168 return NULL;
184169 }
185170
186−/**
187− * tracehook_report_exec - a successful exec was completed
188− * @fmt: &struct linux_binfmt that performed the exec
189− * @bprm: &struct linux_binprm containing exec details
190− * @regs: user-mode register state
191− *
192− * An exec just completed, we are shortly going to return to user mode.
193− * The freshly initialized register state can be seen and changed in @regs.
194− * The name, file and other pointers in @bprm are still on hand to be
195− * inspected, but will be freed as soon as this returns.
196− *
197− * Called with no locks, but with some kernel resources held live
198− * and a reference on @fmt->module.
199− */
200−static inline void tracehook_report_exec(struct linux_binfmt *fmt,
201− struct linux_binprm *bprm,
202− struct pt_regs *regs)
203−{
204− ptrace_event(PTRACE_EVENT_EXEC, 0);
205−}
206−
207−/**
208− * tracehook_report_exit - task has begun to exit
209− * @exit_code: pointer to value destined for @current->exit_code
210− *
211− * @exit_code points to the value passed to do_exit(), which tracing
212− * might change here. This is almost the first thing in do_exit(),
213− * before freeing any resources or setting the %PF_EXITING flag.
214− *
215− * Called with no locks held.
216− */
217−static inline void tracehook_report_exit(long *exit_code)
218−{
219− ptrace_event(PTRACE_EVENT_EXIT, *exit_code);
220−}
221−
222171 /**
223172 * tracehook_prepare_clone - prepare for new child to be cloned
224173 * @clone_flags: %CLONE_* flags from clone/fork/vfork system call
@@ -319,52 +268,6 @@ static inline void tracehook_report_clone_complete(int trace, · 94 unmodified lines
319268 ptrace_event(trace, pid);
320269 }
321270
322−/**
323− * tracehook_report_vfork_done - vfork parent's child has exited or exec'd
324− * @child: child task, already running
325− * @pid: new child's PID in the parent's namespace
326− *
327− * Called after a %CLONE_VFORK parent has waited for the child to complete.
328− * The clone/vfork system call will return immediately after this.
329− * The @child pointer may be invalid if a self-reaping child died and
330− * tracehook_report_clone() took no action to prevent it from self-reaping.
331− *
332− * Called with no locks held.
333− */
334−static inline void tracehook_report_vfork_done(struct task_struct *child,
335− pid_t pid)
336−{
337− ptrace_event(PTRACE_EVENT_VFORK_DONE, pid);
338−}
339−
340−/**
341− * tracehook_prepare_release_task - task is being reaped, clean up tracing
342− * @task: task in %EXIT_DEAD state
343− *
344− * This is called in release_task() just before @task gets finally reaped
345− * and freed. This would be the ideal place to remove and clean up any
346− * tracing-related state for @task.
347− *
348− * Called with no locks held.
349− */
350−static inline void tracehook_prepare_release_task(struct task_struct *task)
351−{
352−}
353−
354−/**
355− * tracehook_finish_release_task - final tracing clean-up
356− * @task: task in %EXIT_DEAD state
357− *
358− * This is called in release_task() when @task is being in the middle of
359− * being reaped. After this, there must be no tracing entanglements.
360− *
361− * Called with write_lock_irq(&tasklist_lock) held.
362− */
363−static inline void tracehook_finish_release_task(struct task_struct *task)
364−{
365− ptrace_release_task(task);
366−}
367−
368271 /**
369272 * tracehook_signal_handler - signal handler setup is complete
370273 * @sig: number of signal being delivered
@@ -388,41 +291,6 @@ static inline void tracehook_signal_handler(int sig, siginfo_t *info, · 17 unmodified lines
388291 ptrace_notify(SIGTRAP);
389292 }
390293
391−/**
392− * tracehook_consider_ignored_signal - suppress short-circuit of ignored signal
393− * @task: task receiving the signal
394− * @sig: signal number being sent
395− *
396− * Return zero iff tracing doesn't care to examine this ignored signal,
397− * so it can short-circuit normal delivery and never even get queued.
398− *
399− * Called with @task->sighand->siglock held.
400− */
401−static inline int tracehook_consider_ignored_signal(struct task_struct *task,
402− int sig)
403−{
404− return (task->ptrace & PT_PTRACED) != 0;
405−}
406−
407−/**
408− * tracehook_consider_fatal_signal - suppress special handling of fatal signal
409− * @task: task receiving the signal
410− * @sig: signal number being sent
411− *
412− * Return nonzero to prevent special handling of this termination signal.
413− * Normally handler for signal is %SIG_DFL. It can be %SIG_IGN if @sig is
414− * ignored, in which case force_sig() is about to reset it to %SIG_DFL.
415− * When this returns zero, this signal might cause a quick termination
416− * that does not give the debugger a chance to intercept the signal.
417− *
418− * Called with or without @task->sighand->siglock held.
419− */
420−static inline int tracehook_consider_fatal_signal(struct task_struct *task,
421− int sig)
422−{
423− return (task->ptrace & PT_PTRACED) != 0;
424−}
425−
426294 #define DEATH_REAP -1
427295 #define DEATH_DELAYED_GROUP_LEADER -2
428296
@@ -457,30 +325,6 @@ static inline int tracehook_notify_death(struct task_struct *task, · 28 unmodified lines
457325 return task->ptrace ? SIGCHLD : DEATH_DELAYED_GROUP_LEADER;
458326 }
459327
460−/**
461− * tracehook_report_death - task is dead and ready to be reaped
462− * @task: @current task now exiting
463− * @signal: return value from tracheook_notify_death()
464− * @death_cookie: value passed back from tracehook_notify_death()
465− * @group_dead: nonzero if this was the last thread in the group to die
466− *
467− * Thread has just become a zombie or is about to self-reap. If positive,
468− * @signal is the signal number just sent to the parent (usually %SIGCHLD).
469− * If @signal is %DEATH_REAP, this thread will self-reap. If @signal is
470− * %DEATH_DELAYED_GROUP_LEADER, this is a delayed_group_leader() zombie.
471− * The @death_cookie was passed back by tracehook_notify_death().
472− *
473− * If normal reaping is not inhibited, @task->exit_state might be changing
474− * in parallel.
475− *
476− * Called without locks.
477− */
478−static inline void tracehook_report_death(struct task_struct *task,
479− int signal, void *death_cookie,
480− int group_dead)
481−{
482−}
483−
484328 #ifdef TIF_NOTIFY_RESUME
485329 /**
486330 * set_notify_resume - cause tracehook_notify_resume() to be called
kernel/exit.c+2−5
@@ -169,7 +169,6 @@ void release_task(struct task_struct * p) · 168 unmodified lines
169169 struct task_struct *leader;
170170 int zap_leader;
171171 repeat:
172− tracehook_prepare_release_task(p);
173172 /* don't need to get the RCU readlock here - the process is dead and
174173 * can't be modifying its own credentials. But shut RCU-lockdep up */
175174 rcu_read_lock();
@@ -179,7 +178,7 @@ repeat: · 3 unmodified lines
179178 proc_flush_task(p);
180179
181180 write_lock_irq(&tasklist_lock);
182− tracehook_finish_release_task(p);
181+ ptrace_release_task(p);
183182 __exit_signal(p);
184183
185184 /*
@@ -868,8 +867,6 @@ static void exit_notify(struct task_struct *tsk, int group_dead) · 682 unmodified lines
868867 wake_up_process(tsk->signal->group_exit_task);
869868 write_unlock_irq(&tasklist_lock);
870869
871− tracehook_report_death(tsk, signal, cookie, group_dead);
872−
873870 /* If the process is dead, release it - nobody will wait for it */
874871 if (signal == DEATH_REAP)
875872 release_task(tsk);
@@ -924,7 +921,7 @@ NORET_TYPE void do_exit(long code) · 48 unmodified lines
924921 */
925922 set_fs(USER_DS);
926923
927− tracehook_report_exit(&code);
924+ ptrace_event(PTRACE_EVENT_EXIT, code);
928925
929926 validate_creds_for_do_exit(tsk);
930927
kernel/fork.c+1−1
@@ -1527,7 +1527,7 @@ long do_fork(unsigned long clone_flags, · 1526 unmodified lines
15271527 freezer_do_not_count();
15281528 wait_for_completion(&vfork);
15291529 freezer_count();
1530− tracehook_report_vfork_done(p, nr);
1530+ ptrace_event(PTRACE_EVENT_VFORK_DONE, nr);
15311531 }
15321532 } else {
15331533 nr = PTR_ERR(p);
kernel/signal.c+4−4
@@ -87,7 +87,7 @@ static int sig_ignored(struct task_struct *t, int sig, int from_ancestor_ns) · 86 unmodified lines
8787 /*
8888 * Tracers may want to know about even ignored signals.
8989 */
90− return !tracehook_consider_ignored_signal(t, sig);
90+ return !t->ptrace;
9191 }
9292
9393 /*
@@ -493,7 +493,8 @@ int unhandled_signal(struct task_struct *tsk, int sig) · 399 unmodified lines
493493 return 1;
494494 if (handler != SIG_IGN && handler != SIG_DFL)
495495 return 0;
496− return !tracehook_consider_fatal_signal(tsk, sig);
496+ /* if ptraced, let the tracer determine */
497+ return !tsk->ptrace;
497498 }
498499
499500 /*
@@ -981,8 +982,7 @@ static void complete_signal(int sig, struct task_struct *p, int group) · 481 unmodified lines
981982 if (sig_fatal(p, sig) &&
982983 !(signal->flags & (SIGNAL_UNKILLABLE | SIGNAL_GROUP_EXIT)) &&
983984 !sigismember(&t->real_blocked, sig) &&
984− (sig == SIGKILL ||
985− !tracehook_consider_fatal_signal(t, sig))) {
985+ (sig == SIGKILL || !t->ptrace)) {
986986 /*
987987 * This signal will be fatal to the whole group.
988988 */
mm/nommu.c+1−2
@@ -22,7 +22,6 @@ · 21 unmodified lines
2222 #include <linux/pagemap.h>
2323 #include <linux/slab.h>
2424 #include <linux/vmalloc.h>
25−#include <linux/tracehook.h>
2625 #include <linux/blkdev.h>
2726 #include <linux/backing-dev.h>
2827 #include <linux/mount.h>
@@ -1087,7 +1086,7 @@ static unsigned long determine_vm_flags(struct file *file, · 1058 unmodified lines
10871086 * it's being traced - otherwise breakpoints set in it may interfere
10881087 * with another untraced process
10891088 */
1090− if ((flags & MAP_PRIVATE) && tracehook_expect_breakpoints(current))
1089+ if ((flags & MAP_PRIVATE) && current->ptrace)
10911090 vm_flags &= ~VM_MAYSHARE;
10921091
10931092 return vm_flags;