On 10/02, Eric W. Biederman wrote: > > syzbot <syzbot+3485e3773f7da290e...@syzkaller.appspotmail.com> writes: > > > Hello, > > > > syzbot found the following issue on: > > So this is: > > static void do_jobctl_trap(void) > { > struct signal_struct *signal = current->signal; > int signr = current->jobctl & JOBCTL_STOP_SIGMASK; > > if (current->ptrace & PT_SEIZED) { > if (!signal->group_stop_count && > !(signal->flags & SIGNAL_STOP_STOPPED)) > signr = SIGTRAP; > WARN_ON_ONCE(!signr); > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > ptrace_do_notify(signr, signr | (PTRACE_EVENT_STOP << 8), > CLD_STOPPED); > } else { > WARN_ON_ONCE(!signr); > ptrace_stop(signr, CLD_STOPPED, 0, NULL); > current->exit_code = 0; > } > } > > I have the state of this paged out of my head at the moment. > > Oleg or Tejun do you remember what is supposed to keep signr from being > NULL?
This nearly killed me, but I seem to understand whats going on. ptrace_init_task() does task_set_jobctl_pending(JOBCTL_TRAP_STOP) while SIGNAL_STOP_STOPPED, child->jobctl & JOBCTL_STOP_SIGMASK == 0. > It looks like this code was introduced in commit 73ddff2bee15 ("job > control: introduce JOBCTL_TRAP_STOP and use it for group stop trap"). Yes, but I bet this was broken later, _may be_ by 924de3b8c9410c4. I need to take a rest and read this code again. I too forgot how this all supposed to work. Oleg.