summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2008-07-23 08:45:25 +0000
committerkib <kib@FreeBSD.org>2008-07-23 08:45:25 +0000
commit42aeaf36b0bea599f34b9841feaa487a33e73f4b (patch)
treefc001659e930de9f8a6db6c444650340bd3078f4
parent5a7f32b6bb42d76d6958416cc0df71e47b7a914e (diff)
downloadFreeBSD-src-42aeaf36b0bea599f34b9841feaa487a33e73f4b.zip
FreeBSD-src-42aeaf36b0bea599f34b9841feaa487a33e73f4b.tar.gz
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
-rw-r--r--sys/kern/kern_fork.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index 6da07d4..e5a3779 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -440,6 +440,7 @@ again:
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 @@ again:
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);
OpenPOWER on IntegriCloud