Commit 8a88951b5878dc475dcd841cefc767e36397d14e
Committed by
Linus Torvalds
1 parent
50b8d25748
Exists in
master
and in
20 other branches
ptrace: ensure JOBCTL_STOP_SIGMASK is not zero after detach
This is the temporary simple fix for 3.2, we need more changes in this area. 1. do_signal_stop() assumes that the running untraced thread in the stopped thread group is not possible. This was our goal but it is not yet achieved: a stopped-but-resumed tracee can clone the running thread which can initiate another group-stop. Remove WARN_ON_ONCE(!current->ptrace). 2. A new thread always starts with ->jobctl = 0. If it is auto-attached and this group is stopped, __ptrace_unlink() sets JOBCTL_STOP_PENDING but JOBCTL_STOP_SIGMASK part is zero, this triggers WANR_ON(!signr) in do_jobctl_trap() if another debugger attaches. Change __ptrace_unlink() to set the artificial SIGSTOP for report. Alternatively we could change ptrace_init_task() to copy signr from current, but this means we can copy it for no reason and hide the possible similar problems. Acked-by: Tejun Heo <tj@kernel.org> Cc: <stable@kernel.org> [3.1] Signed-off-by: Oleg Nesterov <oleg@redhat.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 2 changed files with 12 additions and 3 deletions Side-by-side Diff
kernel/ptrace.c
... | ... | @@ -96,8 +96,19 @@ |
96 | 96 | */ |
97 | 97 | if (!(child->flags & PF_EXITING) && |
98 | 98 | (child->signal->flags & SIGNAL_STOP_STOPPED || |
99 | - child->signal->group_stop_count)) | |
99 | + child->signal->group_stop_count)) { | |
100 | 100 | child->jobctl |= JOBCTL_STOP_PENDING; |
101 | + | |
102 | + /* | |
103 | + * This is only possible if this thread was cloned by the | |
104 | + * traced task running in the stopped group, set the signal | |
105 | + * for the future reports. | |
106 | + * FIXME: we should change ptrace_init_task() to handle this | |
107 | + * case. | |
108 | + */ | |
109 | + if (!(child->jobctl & JOBCTL_STOP_SIGMASK)) | |
110 | + child->jobctl |= SIGSTOP; | |
111 | + } | |
101 | 112 | |
102 | 113 | /* |
103 | 114 | * If transition to TASK_STOPPED is pending or in TASK_TRACED, kick |