A tracee must not return to user mode with ->signal_handler = 1. And, ->signal_handler = 1 must not survive when all detaches are detached.
But, suppose (for simplicity) we have a single engine attached, and utrace_signal_handler() sets ->signal_handler = 1. Suppose signal_pending() = T. The tracee calls get_signal_to_deliver() again. It is possible that the tracee will call tracehook_notify_jctl() before tracehook_get_signal(). Because another thread can start the group stop, or because SIGNAL_STOP_CONTINUED is set. The tracer does UTRACE_DETACH or ->report_jctl() returns UTRACE_DETACH. REPORT()->finish_report() notices report->detaches and calls utrace_reset(). utrace_reset() completes UTRACE_DETACH, and clears ->utrace_flags. The tracee return to user mode bypassing utrace_get_signal() and utrace_resume() because task_utrace_flags() == 0. So far this is OK, the task is not traced. But, when the new tracer attaches, utrace->signal_handler is still true, the next report_signal will use UTRACE_SIGNAL_HANDLER. Signed-off-by: Oleg Nesterov <o...@redhat.com> --- __UTRACE/kernel/utrace.c~2_SIGNAL_HANDLER_LEAK 2009-08-26 12:30:38.000000000 +0200 +++ __UTRACE/kernel/utrace.c 2009-08-26 13:51:10.000000000 +0200 @@ -768,23 +768,20 @@ static void utrace_reset(struct task_str } task->utrace_flags = flags; - - if (wake) - utrace_wakeup(task, utrace); - - /* - * If any engines are left, we're done. - */ - spin_unlock(&utrace->lock); if (!flags) { /* * No more engines, cleared out the utrace. */ + utrace->interrupt = utrace->report = utrace->signal_handler = 0; if (action) *action = UTRACE_RESUME; } + if (wake) + utrace_wakeup(task, utrace); + spin_unlock(&utrace->lock); + put_detached_list(&detached); }