aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/kern_fork.c
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2016-06-27 21:52:17 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2016-06-27 21:52:17 +0000
commit9e590ff04b687e910579a5851d95cedf9eb10bfd (patch)
tree1f2b0dc7608da9e7ac3822cc576909c7e7a41ff5 /sys/kern/kern_fork.c
parent424340f2c7fcf8309af026702e39c354562aa152 (diff)
downloadsrc-9e590ff04b687e910579a5851d95cedf9eb10bfd.tar.gz
src-9e590ff04b687e910579a5851d95cedf9eb10bfd.zip
When filt_proc() removes event from the knlist due to the process
exiting (NOTE_EXIT->knlist_remove_inevent()), two things happen: - knote kn_knlist pointer is reset - INFLUX knote is removed from the process knlist. And, there are two consequences: - KN_LIST_UNLOCK() on such knote is nop - there is nothing which would block exit1() from processing past the knlist_destroy() (and knlist_destroy() resets knlist lock pointers). Both consequences result either in leaked process lock, or dereferencing NULL function pointers for locking. Handle this by stopping embedding the process knlist into struct proc. Instead, the knlist is allocated together with struct proc, but marked as autodestroy on the zombie reap, by knlist_detach() function. The knlist is freed when last kevent is removed from the list, in particular, at the zombie reap time if the list is empty. As result, the knlist_remove_inevent() is no longer needed and removed. Other changes: In filt_procattach(), clear NOTE_EXEC and NOTE_FORK desired events from kn_sfflags for knote registered by kernel to only get NOTE_CHILD notifications. The flags leak resulted in excessive NOTE_EXEC/NOTE_FORK reports. Fix immediate note activation in filt_procattach(). Condition should be either the immediate CHILD_NOTE activation, or immediate NOTE_EXIT report for the exiting process. In knote_fork(), do not perform racy check for KN_INFLUX before kq lock is taken. Besides being racy, it did not accounted for notes just added by scan (KN_SCAN). Some minor and incomplete style fixes. Analyzed and tested by: Eric Badger <eric@badgerio.us> Reviewed by: jhb Sponsored by: The FreeBSD Foundation MFC after: 2 weeks Approved by: re (gjb) Differential revision: https://reviews.freebsd.org/D6859
Notes
Notes: svn path=/head/; revision=302235
Diffstat (limited to 'sys/kern/kern_fork.c')
-rw-r--r--sys/kern/kern_fork.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index 035a704c72fb..b46cb722ce4f 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -748,7 +748,7 @@ do_fork(struct thread *td, struct fork_req *fr, struct proc *p2, struct thread *
/*
* Tell any interested parties about the new process.
*/
- knote_fork(&p1->p_klist, p2->p_pid);
+ knote_fork(p1->p_klist, p2->p_pid);
SDT_PROBE3(proc, , , create, p2, p1, fr->fr_flags);
if (fr->fr_flags & RFPROCDESC) {
@@ -950,7 +950,7 @@ fork1(struct thread *td, struct fork_req *fr)
#ifdef MAC
mac_proc_init(newproc);
#endif
- knlist_init_mtx(&newproc->p_klist, &newproc->p_mtx);
+ newproc->p_klist = knlist_alloc(&newproc->p_mtx);
STAILQ_INIT(&newproc->p_ktr);
/* We have to lock the process tree while we look for a pid. */