diff options
author | cognet <cognet@FreeBSD.org> | 2003-11-14 18:49:01 +0000 |
---|---|---|
committer | cognet <cognet@FreeBSD.org> | 2003-11-14 18:49:01 +0000 |
commit | 690de3f7ac39802c0fe04563dacd6ab0f2a4d79f (patch) | |
tree | ded897c5d2c24412197417991f91d6c4204f76d7 | |
parent | 0cfaf203b6dc7906d6cf6e6df3d4999dec616f45 (diff) | |
download | FreeBSD-src-690de3f7ac39802c0fe04563dacd6ab0f2a4d79f.zip FreeBSD-src-690de3f7ac39802c0fe04563dacd6ab0f2a4d79f.tar.gz |
Better fix than my previous commit:
in exit1(), make sure the p_klist is empty after sending NOTE_EXIT.
The process won't report fork() or execve() and won't be able to handle
NOTE_SIGNAL knotes anyway.
This fixes some race conditions with do_tdsignal() calling knote() while
the process is exiting.
Reported by: Stefan Farfeleder <stefan@fafoe.narf.at>
MFC after: 1 week
-rw-r--r-- | sys/kern/kern_event.c | 10 | ||||
-rw-r--r-- | sys/kern/kern_exit.c | 7 |
2 files changed, 9 insertions, 8 deletions
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c index a0229a7..73139f6 100644 --- a/sys/kern/kern_event.c +++ b/sys/kern/kern_event.c @@ -218,7 +218,8 @@ filt_procattach(struct knote *kn) kn->kn_flags &= ~EV_FLAG1; } - SLIST_INSERT_HEAD(&p->p_klist, kn, kn_selnext); + if (immediate == 0) + SLIST_INSERT_HEAD(&p->p_klist, kn, kn_selnext); /* * Immediately activate any exit notes if the target process is a @@ -280,13 +281,6 @@ filt_proc(struct knote *kn, long hint) } /* - * Process will already be reported as gone. - * Do not report anything else, as the knote will be destroyed soon. - */ - if (kn->kn_status & KN_DETACHED) - return (0); - - /* * process forked, and user wants to track the new process, * so attach a new knote to it, and immediately report an * event with the parent's pid. diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index c65dfeb..10eeac3 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -436,6 +436,13 @@ exit1(struct thread *td, int rv) * Notify interested parties of our demise. */ KNOTE(&p->p_klist, NOTE_EXIT); + /* + * Just delete all entries in the p_klist. At this point we won't + * report any more events, and there are nasty race conditions that + * can beat us if we don't. + */ + while (SLIST_FIRST(&p->p_klist)) + SLIST_REMOVE_HEAD(&p->p_klist, kn_selnext); /* * Notify parent that we're gone. If parent has the PS_NOCLDWAIT |