Revert "fork: fix use-after-free with vfork"
This unreliably breaks libc handling of vfork where forking succeded, but execve did not. vfork code in libc performs waitpid with WNOHANG in case of failed exec. With the fix exit codepath was waking up the parent before the child fully transitioned to a zombie. Woken up parent would waitpid, which could find a not-yet-zombie child and fail to reap it due to the WNOHANG flag. While removing the flag fixes the problem, it is not an option due to older releases which would still suffer from the kernel change. Revert the fix until a solution can be worked out. Note that while use-after-free which gets back due to the revert is a real bug, it's side-effects are limited due to the fact that struct proc memory is never released by UMA.
This commit is contained in:
parent
e9e747efe2
commit
e3d3e8289b
@ -284,15 +284,6 @@ exit1(struct thread *td, int rval, int signo)
|
||||
p->p_flag |= P_WEXIT;
|
||||
wakeup(&p->p_stype);
|
||||
|
||||
/*
|
||||
* If P_PPWAIT is set our parent holds us with p_lock and may
|
||||
* be waiting on p_pwait.
|
||||
*/
|
||||
if (p->p_flag & P_PPWAIT) {
|
||||
p->p_flag &= ~P_PPWAIT;
|
||||
cv_broadcast(&p->p_pwait);
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for any processes that have a hold on our vmspace to
|
||||
* release their reference.
|
||||
@ -338,9 +329,13 @@ exit1(struct thread *td, int rval, int signo)
|
||||
*/
|
||||
EVENTHANDLER_DIRECT_INVOKE(process_exit, p);
|
||||
|
||||
/*
|
||||
* If parent is waiting for us to exit or exec,
|
||||
* P_PPWAIT is set; we will wakeup the parent below.
|
||||
*/
|
||||
PROC_LOCK(p);
|
||||
stopprofclock(p);
|
||||
p->p_flag &= ~(P_TRACED | P_PPTRACE);
|
||||
p->p_flag &= ~(P_TRACED | P_PPWAIT | P_PPTRACE);
|
||||
p->p_ptevents = 0;
|
||||
|
||||
/*
|
||||
@ -641,6 +636,7 @@ exit1(struct thread *td, int rval, int signo)
|
||||
* proc lock.
|
||||
*/
|
||||
wakeup(p->p_pptr);
|
||||
cv_broadcast(&p->p_pwait);
|
||||
sched_exit(p->p_pptr, td);
|
||||
PROC_SLOCK(p);
|
||||
p->p_state = PRS_ZOMBIE;
|
||||
|
@ -720,7 +720,6 @@ do_fork(struct thread *td, struct fork_req *fr, struct proc *p2, struct thread *
|
||||
dtrace_fasttrap_fork(p1, p2);
|
||||
#endif
|
||||
if (fr->fr_flags & RFPPWAIT) {
|
||||
_PHOLD(p2);
|
||||
td->td_pflags |= TDP_RFPPWAIT;
|
||||
td->td_rfppwait_p = p2;
|
||||
td->td_dbgflags |= TDB_VFORK;
|
||||
|
@ -257,7 +257,6 @@ syscallret(struct thread *td, int error)
|
||||
}
|
||||
cv_timedwait(&p2->p_pwait, &p2->p_mtx, hz);
|
||||
}
|
||||
_PRELE(p2);
|
||||
PROC_UNLOCK(p2);
|
||||
|
||||
if (td->td_dbgflags & TDB_VFORK) {
|
||||
|
Loading…
Reference in New Issue
Block a user