diff options
| author | christos <christos@NetBSD.org> | 2006-02-10 17:33:01 +0000 |
|---|---|---|
| committer | christos <christos@NetBSD.org> | 2006-02-10 17:33:01 +0000 |
| commit | 0fa6ea2f2c3633e05e2b758dc33676189ea23b52 (patch) | |
| tree | 0db9a53d5139f3d72a964348f3272f87bb057f7d /sys/dev | |
| parent | 62bee0ffa526f24212494b128f96e49173903a60 (diff) | |
PR/32794: Paul Shupak: Panic in wsmouse code.
Checking the number of events after you've trashed the stack is not very
useful. Instead, break out of the loop if we ran out, printing a message.
Also don't try to inject 0 events; reset our state instead. Maybe having
0 events should be a diagnostic printf at this point? Anyway it is not
nice having the kernel die because the mouse code got confused. Finally,
explain why the array of events is sized funny.
Diffstat (limited to 'sys/dev')
| -rw-r--r-- | sys/dev/wscons/wsmouse.c | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/sys/dev/wscons/wsmouse.c b/sys/dev/wscons/wsmouse.c index 8829f325d47..d23613eaedf 100644 --- a/sys/dev/wscons/wsmouse.c +++ b/sys/dev/wscons/wsmouse.c @@ -1,4 +1,4 @@ -/* $NetBSD: wsmouse.c,v 1.40 2006/02/07 09:13:02 jmmv Exp $ */ +/* $NetBSD: wsmouse.c,v 1.41 2006/02/10 17:33:01 christos Exp $ */ /*- * Copyright (c) 2006 The NetBSD Foundation, Inc. @@ -111,7 +111,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: wsmouse.c,v 1.40 2006/02/07 09:13:02 jmmv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wsmouse.c,v 1.41 2006/02/10 17:33:01 christos Exp $"); #include "wsmouse.h" #include "wsdisplay.h" @@ -346,6 +346,7 @@ wsmouse_input_xyzw(struct device *wsmousedev, u_int btns /* 0 is up */, struct wsmouse_softc *sc = (struct wsmouse_softc *)wsmousedev; struct wseventvar *evar; int mb, ub, d, nevents; + /* one for each dimension (4) + a bit for each button */ struct wscons_event events[4 + sizeof(d) * 8]; /* @@ -463,6 +464,12 @@ wsmouse_input_xyzw(struct device *wsmousedev, u_int btns /* 0 is up */, btnno = ffs(d) - 1; KASSERT(btnno >= 0); + if (nevents >= events / sizeof(events[0])) { + printf("%s: Event queue full (button status mb=0x%x" + " ub=0x%x\n", sc->sc_dev.dv_xname, mb, ub); + break; + } + events[nevents].type = (mb & d) ? WSCONS_EVENT_MOUSE_DOWN : WSCONS_EVENT_MOUSE_UP; events[nevents].value = btnno; @@ -483,10 +490,7 @@ wsmouse_input_xyzw(struct device *wsmousedev, u_int btns /* 0 is up */, } } - KASSERT(nevents > 0 && - nevents <= sizeof(events) / sizeof(struct wscons_event)); - - if (wsevent_inject(evar, events, nevents) == 0) { + if (nevents == 0 || wsevent_inject(evar, events, nevents) == 0) { /* All events were correctly injected into the queue. * Synchronize the mouse's status with what the user * has received. */ |
