Fri Sep 10 10:23:46 2010 UTC ()
make list traversing in knote() safe against removal of the entry
while the loop body is executed -- at least in the EVFILT_PROC / exit
case a race condition exists which can cause this
fixes a panic triggered eg by tests/kernel/kqueue/proc1


(drochner)
diff -r1.70 -r1.71 src/sys/kern/kern_event.c

cvs diff -r1.70 -r1.71 src/sys/kern/kern_event.c (expand / switch to unified diff)

--- src/sys/kern/kern_event.c 2010/07/01 02:38:30 1.70
+++ src/sys/kern/kern_event.c 2010/09/10 10:23:46 1.71
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: kern_event.c,v 1.70 2010/07/01 02:38:30 rmind Exp $ */ 1/* $NetBSD: kern_event.c,v 1.71 2010/09/10 10:23:46 drochner Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. 4 * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Andrew Doran. 8 * by Andrew Doran.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -48,27 +48,27 @@ @@ -48,27 +48,27 @@
48 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 48 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
49 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 49 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
55 * SUCH DAMAGE. 55 * SUCH DAMAGE.
56 * 56 *
57 * FreeBSD: src/sys/kern/kern_event.c,v 1.27 2001/07/05 17:10:44 rwatson Exp 57 * FreeBSD: src/sys/kern/kern_event.c,v 1.27 2001/07/05 17:10:44 rwatson Exp
58 */ 58 */
59 59
60#include <sys/cdefs.h> 60#include <sys/cdefs.h>
61__KERNEL_RCSID(0, "$NetBSD: kern_event.c,v 1.70 2010/07/01 02:38:30 rmind Exp $"); 61__KERNEL_RCSID(0, "$NetBSD: kern_event.c,v 1.71 2010/09/10 10:23:46 drochner Exp $");
62 62
63#include <sys/param.h> 63#include <sys/param.h>
64#include <sys/systm.h> 64#include <sys/systm.h>
65#include <sys/kernel.h> 65#include <sys/kernel.h>
66#include <sys/proc.h> 66#include <sys/proc.h>
67#include <sys/file.h> 67#include <sys/file.h>
68#include <sys/select.h> 68#include <sys/select.h>
69#include <sys/queue.h> 69#include <sys/queue.h>
70#include <sys/event.h> 70#include <sys/event.h>
71#include <sys/eventvar.h> 71#include <sys/eventvar.h>
72#include <sys/poll.h> 72#include <sys/poll.h>
73#include <sys/kmem.h> 73#include <sys/kmem.h>
74#include <sys/stat.h> 74#include <sys/stat.h>
@@ -1450,29 +1450,29 @@ kqueue_kqfilter(file_t *fp, struct knote @@ -1450,29 +1450,29 @@ kqueue_kqfilter(file_t *fp, struct knote
1450 1450
1451 return 0; 1451 return 0;
1452} 1452}
1453 1453
1454 1454
1455/* 1455/*
1456 * Walk down a list of knotes, activating them if their event has 1456 * Walk down a list of knotes, activating them if their event has
1457 * triggered. The caller's object lock (e.g. device driver lock) 1457 * triggered. The caller's object lock (e.g. device driver lock)
1458 * must be held. 1458 * must be held.
1459 */ 1459 */
1460void 1460void
1461knote(struct klist *list, long hint) 1461knote(struct klist *list, long hint)
1462{ 1462{
1463 struct knote *kn; 1463 struct knote *kn, *tmpkn;
1464 1464
1465 SLIST_FOREACH(kn, list, kn_selnext) { 1465 SLIST_FOREACH_SAFE(kn, list, kn_selnext, tmpkn) {
1466 if ((*kn->kn_fop->f_event)(kn, hint)) 1466 if ((*kn->kn_fop->f_event)(kn, hint))
1467 knote_activate(kn); 1467 knote_activate(kn);
1468 } 1468 }
1469} 1469}
1470 1470
1471/* 1471/*
1472 * Remove all knotes referencing a specified fd 1472 * Remove all knotes referencing a specified fd
1473 */ 1473 */
1474void 1474void
1475knote_fdclose(int fd) 1475knote_fdclose(int fd)
1476{ 1476{
1477 struct klist *list; 1477 struct klist *list;
1478 struct knote *kn; 1478 struct knote *kn;