summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoranton <anton@openbsd.org>2020-12-06 07:58:54 +0000
committeranton <anton@openbsd.org>2020-12-06 07:58:54 +0000
commit996a5b4d63fafd69b234669968225849b5adfda2 (patch)
treefde3ee34a1057dc19db9af2934d35620d04e96fd
parentMark bitmask_{start,end}_values[] and g_probable_mtu[] const. (diff)
downloadwireguard-openbsd-996a5b4d63fafd69b234669968225849b5adfda2.tar.xz
wireguard-openbsd-996a5b4d63fafd69b234669968225849b5adfda2.zip
Fix yet another wscons race. In the same subsystem, the following
properties must always hold true: 1. A device (wsmouse0 is this scenario) can only be opened in rw mode once. Such device cannot be a child of a wsmux at this point as it operates on its own event queue. 2. A device being a child of a wsmux must use the wsmux event queue assuming the wsmux is open. Otherwise, its event queue must be NULL. There's a race in wsmux_attach_sc() allowing a device to be part of a mux while using its own event queue. This in turn can cause a NULL pointer deference in wsevent_fini() while closing the same device. The solution is to check if the race was lost, i.e. another thread managed to open the device in rw mode while sleeping in wsmux_attach_sc(). ok gnezdo@ visa@ Reported-by: syzbot+684707f0312345a090ef@syzkaller.appspotmail.com
-rw-r--r--sys/dev/wscons/wsmux.c11
1 files changed, 5 insertions, 6 deletions
diff --git a/sys/dev/wscons/wsmux.c b/sys/dev/wscons/wsmux.c
index 91d3ebdf0a3..35c0c008ef5 100644
--- a/sys/dev/wscons/wsmux.c
+++ b/sys/dev/wscons/wsmux.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: wsmux.c,v 1.51 2020/07/29 05:53:52 anton Exp $ */
+/* $OpenBSD: wsmux.c,v 1.52 2020/12/06 07:58:54 anton Exp $ */
/* $NetBSD: wsmux.c,v 1.37 2005/04/30 03:47:12 augustss Exp $ */
/*
@@ -705,13 +705,12 @@ wsmux_attach_sc(struct wsmux_softc *sc, struct wsevsrc *me)
}
#endif
if (sc->sc_base.me_evp != NULL) {
- /* Mux is open, so open the new subdevice */
- DPRINTF(("%s: %s: calling open of %s\n", __func__,
- sc->sc_base.me_dv.dv_xname, me->me_dv.dv_xname));
+ /* Mux is open, try to open the subdevice. */
error = wsevsrc_open(me, sc->sc_base.me_evp);
} else {
- DPRINTF(("%s: %s not open\n", __func__,
- sc->sc_base.me_dv.dv_xname));
+ /* Mux is closed, ensure that the subdevice is also closed. */
+ if (me->me_evp != NULL)
+ error = EBUSY;
}
if (error) {