[PATCH 62] introduce ptrace_rw_siginfo() helper
Oleg Nesterov
oleg at redhat.com
Wed Oct 7 12:47:33 UTC 2009
On 10/07, Roland McGrath wrote:
>
> > +static int ptrace_rw_siginfo(struct task_struct *tracee,
> > + struct ptrace_context *context,
> > + siginfo_t *info, bool write)
> > +{
> > + unsigned long flags;
> > + siginfo_t *context_info;
> > + int err = -ESRCH;
> > +
> > + if (!lock_task_sighand(tracee, &flags))
> > + return err;
> > + /*
> > + * Make sure the compiler reads ->siginfo only once, if we race
> > + * with SIGKILL ->siginfo can be cleared under us. But the memory
> > + * it points to can't go away, and since we hold ->siglock we can't
> > + * race with get_signal_to_deliver() pathes clobber this memory.
>
> s/pathes clobber/paths that clobber/
Thanks,
> > + * See also the comment in ptrace_report_signal().
> > + */
> > + context_info = ACCESS_ONCE(context->siginfo);
> > + if (context_info) {
> > + if (write)
> > + *context_info = *info;
> > + else
> > + *info = *context_info;
> > + err = 0;
> > + }
> > + unlock_task_sighand(tracee, &flags);
>
> Couldn't we instead do:
>
> context_info = ACCESS_ONCE(context->siginfo);
> if (context_info) {
> *info = *context_info;
> smp_rmb();
> if (ACCESS_ONCE(context->siginfo))
> err = 0;
I don't think this can work. context->siginfo can be cleared and then
set again in between. If we race with SIGKILL, utrace_get_signal()
can dequeue another signal != SIGKILL and start the reporting loop.
I thought about
*info = *context_info;
rmb();
if (fatal_ignal_pending(tracee))
return -ERR;
But I think it is better to do theses cleanups after V1. See also
my reply to next reviews.
Oleg.
More information about the utrace-devel
mailing list