> +     if (context->siginfo)
> +             return ptrace_rw_siginfo(tracee, context, info, false);
>  
> -     return error;
> +     memset(info, 0, sizeof(*info));
> +     info->si_signo = SIGTRAP;
> +     info->si_code = context->ev_code; // XXX: ev_code was already cleared!!!
> +     info->si_pid = task_pid_vnr(tracee);
> +     info->si_uid = task_uid(tracee);

Put that logic inside ptrace_rw_siginfo and call it unconditionally.  It's
going to check context->siginfo anyway.  The forged info is a wrong lie if
it's actually clear because it was set and then there was a SIGKILL, but we
can't tell the difference so a race could yield that bogon anyway.

It probably doesn't really matter to anyone but my pedantic streak, but if
we want to avoid that bogon then we need to leave some further indication
for the SIGKILL case.  Then PTRACE_GETSIGINFO could just return -ESRCH to
appear "after" the death by SIGKILL.

Where exactly does ->siginfo get cleared in that case?  I only see it
cleared in the UTRACE_SIGNAL_REPORT case.  But SIGKILL should not do any
signal reports, it bypasses them and you might get only the DEATH event.
Since you don't request UTRACE_EVENT(DEATH), you'll only get
ptrace_report_quiesce with event==UTRACE_EVENT(DEATH).  
I don't see the path.


Thanks,
Roland

Reply via email to