svn commit: r342899 - releng/11.2/sys/kern
Ed Maste
emaste at FreeBSD.org
Wed Jan 9 18:57:39 UTC 2019
Author: emaste
Date: Wed Jan 9 18:57:38 2019
New Revision: 342899
URL: https://svnweb.freebsd.org/changeset/base/342899
Log:
MFS11 r340904: Avoid unsynchronized updates to kn_status.
Approved by: so
Security: FreeBSD-EN-19:05.kqueue
Modified:
releng/11.2/sys/kern/kern_event.c
Directory Properties:
releng/11.2/ (props changed)
Modified: releng/11.2/sys/kern/kern_event.c
==============================================================================
--- releng/11.2/sys/kern/kern_event.c Wed Jan 9 18:54:42 2019 (r342898)
+++ releng/11.2/sys/kern/kern_event.c Wed Jan 9 18:57:38 2019 (r342899)
@@ -1296,6 +1296,8 @@ findkn:
kn->kn_kevent.flags &= ~(EV_ADD | EV_DELETE |
EV_ENABLE | EV_DISABLE | EV_FORCEONESHOT);
kn->kn_status = KN_INFLUX|KN_DETACHED;
+ if ((kev->flags & EV_DISABLE) != 0)
+ kn->kn_status |= KN_DISABLED;
error = knote_attach(kn, kq);
KQ_UNLOCK(kq);
@@ -1332,6 +1334,11 @@ findkn:
KNOTE_ACTIVATE(kn, 1);
}
+ if ((kev->flags & EV_ENABLE) != 0)
+ kn->kn_status &= ~KN_DISABLED;
+ else if ((kev->flags & EV_DISABLE) != 0)
+ kn->kn_status |= KN_DISABLED;
+
/*
* The user may change some filter values after the initial EV_ADD,
* but doing so will not reset any filter which has already been
@@ -1348,19 +1355,17 @@ findkn:
kn->kn_sdata = kev->data;
}
+done_ev_add:
/*
* We can get here with kn->kn_knlist == NULL. This can happen when
* the initial attach event decides that the event is "completed"
- * already. i.e. filt_procattach is called on a zombie process. It
- * will call filt_proc which will remove it from the list, and NULL
+ * already, e.g., filt_procattach() is called on a zombie process. It
+ * will call filt_proc() which will remove it from the list, and NULL
* kn_knlist.
+ *
+ * KN_DISABLED will be stable while the knote is in flux, so the
+ * unlocked read will not race with an update.
*/
-done_ev_add:
- if ((kev->flags & EV_ENABLE) != 0)
- kn->kn_status &= ~KN_DISABLED;
- else if ((kev->flags & EV_DISABLE) != 0)
- kn->kn_status |= KN_DISABLED;
-
if ((kn->kn_status & KN_DISABLED) == 0)
event = kn->kn_fop->f_event(kn, 0);
else
More information about the svn-src-releng
mailing list