Add "int options" into struct ptrace_context. Will be used to hold PT_XXX options. Currently is not used, but:
- ptrace_attach_task() has a new argument, "int options". Used by ptrace_clone_attach() which should copy the parent's options - introduce __ptrace_set_options() helper which updates ->options and utrace events mask. - change ptrace_attach_task() to use this new helper. --- kernel/ptrace.c | 51 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 15 deletions(-) --- PU/kernel/ptrace.c~17_CTX_EVENTS 2009-09-02 19:48:53.000000000 +0200 +++ PU/kernel/ptrace.c 2009-09-02 19:53:06.000000000 +0200 @@ -25,8 +25,15 @@ #include <linux/uaccess.h> struct ptrace_context { + int options; }; +static inline +struct ptrace_context *ptrace_context(struct utrace_engine *engine) +{ + return engine->data; +} + /* * ptrace a task: make the debugger its new parent and * move it to the ptrace list. @@ -41,7 +48,7 @@ void __ptrace_link(struct task_struct *c } static const struct utrace_engine_ops ptrace_utrace_ops; /* forward decl */ -static int ptrace_attach_task(struct task_struct *tracee); +static int ptrace_attach_task(struct task_struct *tracee, int options); static void ptrace_abort_attach(struct task_struct *tracee); static void ptrace_detach_task(struct task_struct *child, int sig) @@ -216,14 +223,15 @@ static u32 ptrace_report_exit(enum utrac } static void ptrace_clone_attach(struct task_struct *parent, - struct task_struct *child) + struct task_struct *child, + int options) { struct task_struct *tracer; bool abort = true; if (!parent->ptrace) return; - if (unlikely(ptrace_attach_task(child))) { + if (unlikely(ptrace_attach_task(child, options))) { WARN_ON(1); return; } @@ -252,6 +260,7 @@ static u32 ptrace_report_clone(enum utra unsigned long clone_flags, struct task_struct *child) { + struct ptrace_context *context = ptrace_context(engine); int event; if ((clone_flags & CLONE_VFORK) && @@ -289,7 +298,7 @@ static u32 ptrace_report_clone(enum utra * So does CLONE_PTRACE, even with no event to report. */ if (event || (clone_flags & CLONE_PTRACE)) - ptrace_clone_attach(parent, child); + ptrace_clone_attach(parent, child, context->options); if (event) return utrace_ptrace_event(parent, event, child->pid); @@ -485,15 +494,33 @@ static const struct utrace_engine_ops pt .release = ptrace_release, }; +static inline int __ptrace_set_options(struct task_struct *target, + struct utrace_engine *engine, + unsigned long options) +{ + struct ptrace_context *context = ptrace_context(engine); + /* + * We need QUIESCE for resume handling, CLONE to check + * for CLONE_PTRACE, other events are always reported. + */ + unsigned long events = UTRACE_EVENT(QUIESCE) | UTRACE_EVENT(CLONE) | + UTRACE_EVENT(EXEC) | UTRACE_EVENT_SIGNAL_ALL; + + context->options = options; + if (options & PT_TRACE_EXIT) + events |= UTRACE_EVENT(EXIT); + + return utrace_set_events(target, engine, events); +} + /* * Attach a utrace engine for ptrace and set up its event mask. * Returns error code or 0 on success. */ -static int ptrace_attach_task(struct task_struct *tracee) +static int ptrace_attach_task(struct task_struct *tracee, int options) { struct ptrace_context *context; struct utrace_engine *engine; - unsigned long events; int err; context = kzalloc(sizeof(*context), GFP_KERNEL); @@ -512,16 +539,10 @@ static int ptrace_attach_task(struct tas return err; } /* - * We need QUIESCE for resume handling, CLONE to check - * for CLONE_PTRACE, other events are always reported. - */ - events = UTRACE_EVENT(QUIESCE) | UTRACE_EVENT(CLONE) | - UTRACE_EVENT(EXEC) | UTRACE_EVENT_SIGNAL_ALL; - /* * It can fail only if the tracee is dead, the caller * must notice this before setting PT_PTRACED. */ - err = utrace_set_events(tracee, engine, events); + err = __ptrace_set_options(tracee, engine, options); WARN_ON(err && !tracee->exit_state); utrace_engine_put(engine); return 0; @@ -634,7 +655,7 @@ int ptrace_attach(struct task_struct *ta if (retval) goto unlock_creds; - retval = ptrace_attach_task(task); + retval = ptrace_attach_task(task, 0); if (unlikely(retval)) goto unlock_creds; @@ -669,7 +690,7 @@ out: int ptrace_traceme(void) { bool detach = true; - int ret = ptrace_attach_task(current); + int ret = ptrace_attach_task(current, 0); if (unlikely(ret)) return ret;