diff options
author | anton <anton@cvs.openbsd.org> | 2019-05-22 18:52:15 +0000 |
---|---|---|
committer | anton <anton@cvs.openbsd.org> | 2019-05-22 18:52:15 +0000 |
commit | 3f1dd8d2335d348d20376202ec9ef7098662248e (patch) | |
tree | 83150de3ebaf48c58ed281a512f08e7baf90b000 | |
parent | 0218d2364b8dbd7d1fac92150c117dd08e20c7b6 (diff) |
A wscons device may only be opened in read/write mode once. However,
after checking for exclusive access, malloc() can sleep in
wsevent_init() opening up for a potential race where more than one
thread may be able open the device. Prevent this by checking if the race
was won after calling malloc().
While here, switch to mallocarray as proposed by both cheloha@ and mpi@
ok mpi@
-rw-r--r-- | sys/dev/wscons/wsevent.c | 22 | ||||
-rw-r--r-- | sys/dev/wscons/wseventvar.h | 4 | ||||
-rw-r--r-- | sys/dev/wscons/wskbd.c | 5 | ||||
-rw-r--r-- | sys/dev/wscons/wsmouse.c | 5 | ||||
-rw-r--r-- | sys/dev/wscons/wsmux.c | 5 |
5 files changed, 25 insertions, 16 deletions
diff --git a/sys/dev/wscons/wsevent.c b/sys/dev/wscons/wsevent.c index be015534317..8518bfc56e1 100644 --- a/sys/dev/wscons/wsevent.c +++ b/sys/dev/wscons/wsevent.c @@ -1,4 +1,4 @@ -/* $OpenBSD: wsevent.c,v 1.19 2019/02/01 17:23:08 anton Exp $ */ +/* $OpenBSD: wsevent.c,v 1.20 2019/05/22 18:52:14 anton Exp $ */ /* $NetBSD: wsevent.c,v 1.16 2003/08/07 16:31:29 agc Exp $ */ /* @@ -98,21 +98,27 @@ const struct filterops wsevent_filtops = { /* * Initialize a wscons_event queue. */ -void +int wsevent_init(struct wseventvar *ev) { + struct wscons_event *queue; + + if (ev->q != NULL) + return (0); + queue = mallocarray(WSEVENT_QSIZE, sizeof(struct wscons_event), + M_DEVBUF, M_WAITOK | M_ZERO); if (ev->q != NULL) { -#ifdef DIAGNOSTIC - printf("wsevent_init: already initialized\n"); -#endif - return; + free(queue, M_DEVBUF, WSEVENT_QSIZE * sizeof(struct wscons_event)); + return (1); } + + ev->q = queue; ev->get = ev->put = 0; - ev->q = malloc(WSEVENT_QSIZE * sizeof(struct wscons_event), - M_DEVBUF, M_WAITOK | M_ZERO); sigio_init(&ev->sigio); + + return (0); } /* diff --git a/sys/dev/wscons/wseventvar.h b/sys/dev/wscons/wseventvar.h index 5424fff9dc5..5042b81cb9c 100644 --- a/sys/dev/wscons/wseventvar.h +++ b/sys/dev/wscons/wseventvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: wseventvar.h,v 1.9 2018/11/19 19:19:24 anton Exp $ */ +/* $OpenBSD: wseventvar.h,v 1.10 2019/05/22 18:52:14 anton Exp $ */ /* $NetBSD: wseventvar.h,v 1.1 1998/03/22 14:24:03 drochner Exp $ */ /* @@ -104,7 +104,7 @@ struct wseventvar { pgsigio(&(ev)->sigio, SIGIO, 0); \ } -void wsevent_init(struct wseventvar *); +int wsevent_init(struct wseventvar *); void wsevent_fini(struct wseventvar *); int wsevent_read(struct wseventvar *, struct uio *, int); int wsevent_poll(struct wseventvar *, int, struct proc *); diff --git a/sys/dev/wscons/wskbd.c b/sys/dev/wscons/wskbd.c index 49a08976c3a..b89e95f9b33 100644 --- a/sys/dev/wscons/wskbd.c +++ b/sys/dev/wscons/wskbd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: wskbd.c,v 1.96 2019/02/19 07:01:02 anton Exp $ */ +/* $OpenBSD: wskbd.c,v 1.97 2019/05/22 18:52:14 anton Exp $ */ /* $NetBSD: wskbd.c,v 1.80 2005/05/04 01:52:16 augustss Exp $ */ /* @@ -824,7 +824,8 @@ wskbdopen(dev_t dev, int flags, int mode, struct proc *p) return (EBUSY); evar = &sc->sc_base.me_evar; - wsevent_init(evar); + if (wsevent_init(evar)) + return (EBUSY); error = wskbd_do_open(sc, evar); if (error) { diff --git a/sys/dev/wscons/wsmouse.c b/sys/dev/wscons/wsmouse.c index 73c304bd53e..57ea83a6aab 100644 --- a/sys/dev/wscons/wsmouse.c +++ b/sys/dev/wscons/wsmouse.c @@ -1,4 +1,4 @@ -/* $OpenBSD: wsmouse.c,v 1.52 2019/03/24 18:04:02 bru Exp $ */ +/* $OpenBSD: wsmouse.c,v 1.53 2019/05/22 18:52:14 anton Exp $ */ /* $NetBSD: wsmouse.c,v 1.35 2005/02/27 00:27:52 perry Exp $ */ /* @@ -330,7 +330,8 @@ wsmouseopen(dev_t dev, int flags, int mode, struct proc *p) return (EBUSY); evar = &sc->sc_base.me_evar; - wsevent_init(evar); + if (wsevent_init(evar)) + return (EBUSY); error = wsmousedoopen(sc, evar); if (error) { diff --git a/sys/dev/wscons/wsmux.c b/sys/dev/wscons/wsmux.c index 28f6815d91f..ca733362175 100644 --- a/sys/dev/wscons/wsmux.c +++ b/sys/dev/wscons/wsmux.c @@ -1,4 +1,4 @@ -/* $OpenBSD: wsmux.c,v 1.46 2019/05/21 20:57:10 anton Exp $ */ +/* $OpenBSD: wsmux.c,v 1.47 2019/05/22 18:52:14 anton Exp $ */ /* $NetBSD: wsmux.c,v 1.37 2005/04/30 03:47:12 augustss Exp $ */ /* @@ -209,7 +209,8 @@ wsmuxopen(dev_t dev, int flags, int mode, struct proc *p) return (EBUSY); evar = &sc->sc_base.me_evar; - wsevent_init(evar); + if (wsevent_init(evar)) + return (EBUSY); #ifdef WSDISPLAY_COMPAT_RAWKBD sc->sc_rawkbd = 0; #endif |