On 10/12, Roland McGrath wrote:
>
> > Suppose a tracee is running, but for some reason it is somewhere
> > inside start_callback(). utrace_control(UTRACE_STOP) can change ->flags
> > and provoke report->action = UTRACE_STOP. In this case the tracee will
> > stop.
>
> And then you check whether it's really in a proper ptrace stop, see that it
> isn't, and use UTRACE_RESUME.

So far I don't really understand to do this correctly, but OK.

> > IOW. The tracee is running, say, it does "for (;;) ;". If the tracer
> > does
> >     for (;;)
> >             ptrace(PTRACE_CONT);
> >
> > it can stop the tracee.
>
> No.

I meant, currently it can.

> > I don't think we have security issues, ptrace_check_attach() is only
> > called when we already ptrace the task. 
>
> It is called to verify that we already ptrace the task.
> That's the point.
>
> > It is a bit racy, we should
> > check child->parent after ptrace_lookup_engine(), but this is trivial.
>
> As I said, as long as we verify that we are the attached ptracer before
> calling utrace_control, there is no security issue.

ptrace_check_attach() does verify we are ptracer. If the task has
ptrace_utrace_ops engine and we are ->parent - we ptrace this task.

> > We already have the indicator - get_stop_event(). Except it doesn't work
> > for jctl stops. ptrace_check_attach() needs something like:
> >
> >     if (!ptrace_event_pending()) {
> >             do not change engine->flags,
> >             do not set utrace->report,
> >             just s/TASK_STOPPED/TASK_TRACED/ or fail
> >     }
>
> utrace_control(,,UTRACE_STOP) does s/TASK_STOPPED/TASK_TRACED/.  That's
> what I was just saying.  If it returns -EINPROGRESS, then it wasn't really
> in TASK_STOPPED, so you can do UTRACE_RESUME and then fail with -ESRCH.
> (In that race, you could get a report_quiesce or UTRACE_REPORT_SIGNAL,
> and those just need to know to do nothing if (!ptrace_event_pending()).)

Yes. I meant, perhaps it would be nice to have a "passive" method to
check if it stopped or not via utrace API.

> That alone succeeds when it shouldn't, if there is another engine keeping
> it in TASK_TRACED already so that utrace_control returns zero.  To rule
> that out we might use report_jctl to do some more bookkeeping.

Yes. ptrace should use report_jctl() anyway to solve other problems
with jctl stops, but lets discuss this later.
> I
> wonder if we could make ->state = TASK_STOPPED|TASK_TRACED work to keep
> task_is_stopped() as a meaningful test while in UTRACE_STOP.

Hmm. Never thought about this! looks interesting and useful to me...

Oleg.

Reply via email to