diff options
author | 2016-06-13 10:15:03 +0000 | |
---|---|---|
committer | 2016-06-13 10:15:03 +0000 | |
commit | 1021ea4ff7dd2a1dbdd53e71bb5dbc45f9f433af (patch) | |
tree | a74437fd679326405238a23f70d8e293a8620800 | |
parent | correct pledge for disklabel -R -[fF] (diff) | |
download | wireguard-openbsd-1021ea4ff7dd2a1dbdd53e71bb5dbc45f9f433af.tar.xz wireguard-openbsd-1021ea4ff7dd2a1dbdd53e71bb5dbc45f9f433af.zip |
Do not execute the callback if the device is beeing detached.
Should prevent a race triggering a use-after-free reported by
martijn@ on bugs@
-rw-r--r-- | sys/dev/usb/uhidev.c | 25 |
1 files changed, 13 insertions, 12 deletions
diff --git a/sys/dev/usb/uhidev.c b/sys/dev/usb/uhidev.c index 2598e2d5868..256ec08933d 100644 --- a/sys/dev/usb/uhidev.c +++ b/sys/dev/usb/uhidev.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uhidev.c,v 1.73 2016/01/09 04:14:42 jcs Exp $ */ +/* $OpenBSD: uhidev.c,v 1.74 2016/06/13 10:15:03 mpi Exp $ */ /* $NetBSD: uhidev.c,v 1.14 2003/03/11 16:44:00 augustss Exp $ */ /* @@ -96,8 +96,7 @@ void uhidev_attach(struct device *, struct device *, void *); int uhidev_detach(struct device *, int); int uhidev_activate(struct device *, int); -void uhidev_get_report_async_cb(struct usbd_xfer *xfer, void *priv, - usbd_status status); +void uhidev_get_report_async_cb(struct usbd_xfer *, void *, usbd_status); struct cfdriver uhidev_cd = { NULL, "uhidev", DV_DULL @@ -754,17 +753,19 @@ uhidev_get_report_async_cb(struct usbd_xfer *xfer, void *priv, usbd_status err) char *buf; int len = -1; - if (err == USBD_NORMAL_COMPLETION || err == USBD_SHORT_XFER) { - len = xfer->actlen; - buf = KERNADDR(&xfer->dmabuf, 0); - if (info->id > 0) { - len--; - memcpy(info->data, buf + 1, len); - } else { - memcpy(info->data, buf, len); + if (!usbd_is_dying(xfer->pipe->device)) { + if (err == USBD_NORMAL_COMPLETION || err == USBD_SHORT_XFER) { + len = xfer->actlen; + buf = KERNADDR(&xfer->dmabuf, 0); + if (info->id > 0) { + len--; + memcpy(info->data, buf + 1, len); + } else { + memcpy(info->data, buf, len); + } } + info->callback(info->priv, info->id, info->data, len); } - info->callback(info->priv, info->id, info->data, len); free(info, M_TEMP, sizeof(*info)); usbd_free_xfer(xfer); } |