> But ptrace_check_attach() needs the tracee to be already stopped. > A bit ugly to ask the tracee to stop via UTRACE_STOP and then resume > it if it was not already stopped. And I don't even understand how to > do this correctly. (but again, I'll try to think later).
Ugly, but correct and simple. It's only ugly when called in an error case. > Apart from utrace_prepare_examine()->wait_task_inactive() and security > checks, ptrace_check_attach() should do something like > > if (!task_stop_or_traced()) > FAIL; > > if (SIGNAL_STOP_STOPPED || // JCTL stop > get_stop_event()) { // it was stopped by us > > ... OK. s/STOPPED/TRACED/ and proceed .. > } > > FAIL; Right. That is fine as long as there are no races that can confuse it. I don't see any off hand. > Not sure. Suppose the tracer does PTRACE_SYSCALL and the tracee spins in > user-mode. Another engine stops the tracee. In this case any ptrace() > request should fail despite the fact the tracee is STOPPED or TRACED. Correct (if it's in TASK_TRACED, not TASK_STOPPED). It needs to test the ptrace-stoppedness state in ptrace_context. You only need any UTRACE_STOP-related logic to counter any possible races with wakeup. i.e., if the stoppedness state is still left when you resume and cleared by the tracee's own callbacks, you would get a false positive in case the tracee had not been scheduled yet. Since the ptrace-stoppedness should never be indicated without the engine being in UTRACE_STOP state, the only other race is with SIGKILL wakeups. That one probably doesn't matter, since it's no different from the SIGKILL wakeup coming just after ptrace_check_attach() returns 0. Thanks, Roland