Page MenuHomeFreeBSD

Only reparent a traced process to its old parent if the tracing process is not the old parent.
ClosedPublic

Authored by jhb on May 19 2015, 8:06 PM.
Tags
None
Referenced Files
Unknown Object (File)
Sun, May 5, 7:38 AM
Unknown Object (File)
Sun, May 5, 7:18 AM
Unknown Object (File)
Fri, May 3, 3:34 AM
Unknown Object (File)
Fri, May 3, 3:27 AM
Unknown Object (File)
Tue, Apr 30, 7:25 AM
Unknown Object (File)
Tue, Apr 30, 2:17 AM
Unknown Object (File)
Fri, Apr 26, 8:16 AM
Unknown Object (File)
Fri, Apr 26, 8:16 AM
Subscribers

Details

Summary

Only reparent a traced process to its old parent if the tracing process is
not the old parent. Otherwise, proc_reap() will leave the zombie in place
resulting in the process' status being returned twice to its parent.

Add test cases for PT_TRACE_ME and PT_ATTACH which are fixed by
this change.

Test Plan
  • I wrote an ATF test case for this that is included in the change. It currently fails as the last waitpid does not fail, but returns the child process a second time (verified via ktrace).

Diff Detail

Repository
rS FreeBSD src repository - subversion
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

jhb retitled this revision from to Don't set p_oppid for a process traced by its parent via PT_TRACE_ME..
jhb updated this object.
jhb edited the test plan for this revision. (Show Details)
jhb added a reviewer: kib.

Isn't the same situation occur when PT_ATTACH is performed on the direct child ?

Myself, I would fix the issue by the check in proc_reap(), comparing the p_oppid to the parent pid. Note that PT_DETACH already does the same check.

Mmm, how about I fix in both places? That is, fix PT_ATTACH to only set oppid hen it reparents, but also add the check in proc_reap() (or we could change proc_reap() to assert that if oppid is set it doesn't match the existing parent).

In D2594#48133, @jhb wrote:

Mmm, how about I fix in both places? That is, fix PT_ATTACH to only set oppid hen it reparents, but also add the check in proc_reap() (or we could change proc_reap() to assert that if oppid is set it doesn't match the existing parent).

I sounds good either way. If you change PT_ATTACH, then assert in the proc_reap() seems to be most logical.

Hmm, I actually think I will just fix proc_reap(). It is a smaller change. Otherwise I'd need to fix PT_DETACH to ignore a oppid of 0. Note that procfs only sets oppid if it reparents, but it always tries to reparent in detach. I will fix procfs to always set oppid in my next update, though I probably won't bother testing procfs, just ptrace.

jhb edited edge metadata.
  • Add the same double-wait test for PT_ATTACH().
  • Revert previous and check for parent == tracer in exit.
jhb retitled this revision from Don't set p_oppid for a process traced by its parent via PT_TRACE_ME. to Only reparent a traced process to its old parent if the tracing process is not the old parent..May 20 2015, 3:05 AM
jhb updated this object.

Tested.

sys/kern/kern_exit.c
856 ↗(On Diff #5503)

I believe that p_oppid must be cleared if not zero, regardless of its value.

  • Always clear p_oppid.
kib edited edge metadata.
This revision is now accepted and ready to land.May 20 2015, 2:36 PM
This revision was automatically updated to reflect the committed changes.