Module Name: src Committed By: kamil Date: Thu Jun 13 20:20:18 UTC 2019
Modified Files: src/sys/kern: kern_exec.c kern_exit.c kern_fork.c src/sys/sys: lwp.h Log Message: Correct use-after-free issue in vfork(2) In the previous behavior vforking parent was keeping pointer to a child and checking whether it clears a PL_PPWAIT in its bitfield p_lflag. However a child can go invalid between exec/exit event from child and waking up vforked parent and this can cause invalid pointer read and in the worst scenario kernel crash. In the new behavior vforked child keeps a reference to vforked parent LWP and sets a value l_vforkwaiting to false. This means that vforked child can finish its work, exec/exit and be terminated and once parent will be woken up it will read its own field whether its child is still blocking. Add new field in struct lwp: l_vforkwaiting protected by proc_lock. In future it should be refactored and all PL_PPWAIT users transformed to l_vforkwaiting and next l_vforkwaiting probably transformed into a bit field. This is another attempt of fixing this bug after <rmind> from 2012 in commit: Author: rmind <rm...@netbsd.org> Date: Sun Jul 22 22:40:18 2012 +0000 fork1: fix use-after-free problems. Addresses PR/46128 from Andrew Doran. Note: PL_PPWAIT should be fully replaced and modificaiton of l_pflag by other LWP is undesirable, but this is enough for netbsd-6. The new version no longer performs unsafe access in l_lflag changing the LP_VFORKWAIT bit. Verified with ATF t_vfork and t_ptrace* tests and they are no longer causing any issues in my local setup. Fixes PR/46128 by Andrew Doran To generate a diff of this commit: cvs rdiff -u -r1.466 -r1.467 src/sys/kern/kern_exec.c cvs rdiff -u -r1.275 -r1.276 src/sys/kern/kern_exit.c cvs rdiff -u -r1.212 -r1.213 src/sys/kern/kern_fork.c cvs rdiff -u -r1.183 -r1.184 src/sys/sys/lwp.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.