Do the pargs_hold() on the copy of the pointer to the p_args of the

child process immediately after bulk bcopy() without dropping the
process lock.

Since process is not single-threaded when forking, dropping and
reacquiring the lock allows an other thread to change the process title
of the parent in between, and results in hold being done on the invalid
pointer. The problem manifested itself as the double free of the old
p_args.

Reported by:	kris
Reviewed by:	jhb
MFC after:	1 week
This commit is contained in:
Konstantin Belousov 2008-07-23 08:45:25 +00:00
parent 33f0efe6b0
commit 8b4a2800de

View File

@ -440,6 +440,7 @@ fork1(td, flags, pages, procp)
bcopy(&p1->p_startcopy, &p2->p_startcopy,
__rangeof(struct proc, p_startcopy, p_endcopy));
pargs_hold(p2->p_args);
PROC_UNLOCK(p1);
bzero(&p2->p_startzero,
@ -520,7 +521,6 @@ fork1(td, flags, pages, procp)
if (p1->p_flag & P_PROFIL)
startprofclock(p2);
td2->td_ucred = crhold(p2->p_ucred);
pargs_hold(p2->p_args);
if (flags & RFSIGSHARE) {
p2->p_sigacts = sigacts_hold(p1->p_sigacts);