Convert ptrace to use utrace_set_caps(). ptrace_report_clone() uses utrace_get_caps() and PT_UTRACED instead of parent->ptrace.
Henceforth task_struct->ptrace is only used for PT_UTRACED, and this bit can be moved into ENGINE_EXTRA_FLAGS. utrace_unsafe_exec() doesn't need to play with task->ptrace any longer. --- kernel/ptrace-utrace.c | 18 ++++++++---------- kernel/utrace.c | 6 ------ 2 files changed, 8 insertions(+), 16 deletions(-) --- RHEL6/kernel/ptrace-utrace.c~5_CONVERT_PTRACE 2010-05-20 12:40:50.000000000 +0200 +++ RHEL6/kernel/ptrace-utrace.c 2010-07-07 02:59:52.000000000 +0200 @@ -198,7 +198,7 @@ static inline int ptrace_set_events(stru * 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, int options) +static int ptrace_attach_task(struct task_struct *tracee, int options, int caps) { struct utrace_engine *engine; int err; @@ -295,13 +295,13 @@ static u32 ptrace_report_exit(u32 action } static void ptrace_clone_attach(struct task_struct *child, - int options) + int options, int caps) { struct task_struct *parent = current; struct task_struct *tracer; bool abort = true; - if (unlikely(ptrace_attach_task(child, options))) { + if (unlikely(ptrace_attach_task(child, options, caps))) { WARN_ON(1); return; } @@ -309,7 +309,7 @@ static void ptrace_clone_attach(struct t write_lock_irq(&tasklist_lock); tracer = parent->parent; if (!(tracer->flags & PF_EXITING) && parent->ptrace) { - child->ptrace = parent->ptrace; + child->ptrace = PT_UTRACED; __ptrace_link(child, tracer); abort = false; } @@ -351,7 +351,8 @@ static u32 ptrace_report_clone(u32 actio */ if ((event && event != PTRACE_EVENT_VFORK_DONE) || (clone_flags & CLONE_PTRACE)) - ptrace_clone_attach(child, ctx->options); + ptrace_clone_attach(child, ctx->options, + utrace_get_caps(engine)); if (!event) return UTRACE_RESUME; @@ -632,7 +633,7 @@ int ptrace_attach(struct task_struct *ta if (retval) goto unlock_creds; - retval = ptrace_attach_task(task, 0); + retval = ptrace_attach_task(task, 0, capable(CAP_SYS_PTRACE)); if (unlikely(retval)) goto unlock_creds; @@ -643,9 +644,6 @@ int ptrace_attach(struct task_struct *ta BUG_ON(task->ptrace); task->ptrace = PT_UTRACED; - if (capable(CAP_SYS_PTRACE)) - task->ptrace |= PT_PTRACE_CAP; - __ptrace_link(task, current); send_sig_info(SIGSTOP, SEND_SIG_FORCED, task); @@ -665,7 +663,7 @@ out: int ptrace_traceme(void) { bool detach = true; - int ret = ptrace_attach_task(current, 0); + int ret = ptrace_attach_task(current, 0, 0); if (unlikely(ret)) return ret; --- RHEL6/kernel/utrace.c~5_CONVERT_PTRACE 2010-07-07 02:41:31.000000000 +0200 +++ RHEL6/kernel/utrace.c 2010-07-07 19:16:19.000000000 +0200 @@ -2494,11 +2494,5 @@ int utrace_unsafe_exec(struct task_struc else if (task->utrace_flags & ENGINE_LSM_TRACE_CAP) unsafe = LSM_UNSAFE_PTRACE_CAP; - if (task->ptrace & PT_PTRACE_CAP) { - if (!unsafe) - unsafe = LSM_UNSAFE_PTRACE_CAP; - } else if (task->ptrace) - unsafe = LSM_UNSAFE_PTRACE; - return unsafe; }