diff options
author | kib <kib@FreeBSD.org> | 2008-07-23 08:45:25 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2008-07-23 08:45:25 +0000 |
commit | 42aeaf36b0bea599f34b9841feaa487a33e73f4b (patch) | |
tree | fc001659e930de9f8a6db6c444650340bd3078f4 /sys/kern | |
parent | 5a7f32b6bb42d76d6958416cc0df71e47b7a914e (diff) | |
download | FreeBSD-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
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/kern_fork.c | 2 |
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); |