(relies on 471d6f49e9b9be7830adf1a47f18f5ba90a05041 "utrace_engine_ops: add release hook" in utrace-dtor)
Introduce the empty struct ptrace_context, change ptrace_attach_task() to setup engine->data. It should be used for ptrace_set_action() and ptrace_set_stop_event(), the current usage of ->ptrace is racy. Also, ->exit_code and ->last_siginfo should live in engine->data too. Eventually, all ptrace-related members should be moved from task_struct. --- kernel/ptrace.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) --- PU/kernel/ptrace.c~16_PTRACE_CONTEXT 2009-09-02 17:50:58.000000000 +0200 +++ PU/kernel/ptrace.c 2009-09-02 19:48:53.000000000 +0200 @@ -24,6 +24,8 @@ #include <linux/syscalls.h> #include <linux/uaccess.h> +struct ptrace_context { +}; /* * ptrace a task: make the debugger its new parent and @@ -467,6 +469,11 @@ static u32 ptrace_report_quiesce(u32 act return ptrace_resume_action(task); } +static void ptrace_release(void *data) +{ + kfree(data); +} + static const struct utrace_engine_ops ptrace_utrace_ops = { .report_signal = ptrace_report_signal, .report_quiesce = ptrace_report_quiesce, @@ -475,6 +482,7 @@ static const struct utrace_engine_ops pt .report_clone = ptrace_report_clone, .report_syscall_entry = ptrace_report_syscall_entry, .report_syscall_exit = ptrace_report_syscall_exit, + .release = ptrace_release, }; /* @@ -483,18 +491,24 @@ static const struct utrace_engine_ops pt */ static int ptrace_attach_task(struct task_struct *tracee) { + struct ptrace_context *context; struct utrace_engine *engine; unsigned long events; int err; + context = kzalloc(sizeof(*context), GFP_KERNEL); + if (unlikely(!context)) + return -ENOMEM; + engine = utrace_attach_task(tracee, UTRACE_ATTACH_CREATE | UTRACE_ATTACH_EXCLUSIVE | UTRACE_ATTACH_MATCH_OPS, - &ptrace_utrace_ops, NULL); + &ptrace_utrace_ops, context); if (unlikely(IS_ERR(engine))) { err = PTR_ERR(engine); if (err != -ESRCH && err != -ERESTARTNOINTR) err = -EPERM; + kfree(context); return err; } /*