diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2016-01-14 21:21:27 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2016-01-14 21:21:27 +0000 |
commit | 6907d0e322a04bbd8343b995c270278601913d37 (patch) | |
tree | 91eba88f857e80e161f9cc96be15101907ff5f27 /sys | |
parent | 00844ad1393ad7e38e1216687fe629b809869ea1 (diff) |
When iterating over the report IDs to calculate the maximum size, take
into account the 2 bytes needed to store the length. Also make sure
that we have at least wMaxInputLength bytes available for reading input
reports.
ok jcs@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/i2c/ihidev.c | 30 |
1 files changed, 14 insertions, 16 deletions
diff --git a/sys/dev/i2c/ihidev.c b/sys/dev/i2c/ihidev.c index 5ab2ffefdd8..1685aa3228a 100644 --- a/sys/dev/i2c/ihidev.c +++ b/sys/dev/i2c/ihidev.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ihidev.c,v 1.4 2016/01/13 15:10:35 jcs Exp $ */ +/* $OpenBSD: ihidev.c,v 1.5 2016/01/14 21:21:26 kettenis Exp $ */ /* * HID-over-i2c driver * @@ -114,6 +114,7 @@ ihidev_attach(struct device *parent, struct device *self, void *aux) struct device *dev; int repid, repsz; int repsizes[256]; + int isize; sc->sc_tag = ia->ia_tag; sc->sc_addr = ia->ia_addr; @@ -159,13 +160,16 @@ ihidev_attach(struct device *parent, struct device *self, void *aux) return; } - sc->sc_isize = 0; + sc->sc_isize = letoh16(sc->hid_desc.wMaxInputLength); for (repid = 0; repid < sc->sc_nrepid; repid++) { repsz = hid_report_size(sc->sc_report, sc->sc_reportlen, hid_input, repid); repsizes[repid] = repsz; - if (repsz > sc->sc_isize) - sc->sc_isize = repsz; + + isize = repsz + 2; /* two bytes for the length */ + isize += (sc->sc_nrepid != 1); /* one byte for the report ID */ + if (isize > sc->sc_isize) + sc->sc_isize = isize; DPRINTF(("%s: repid %d size %d\n", sc->sc_dev.dv_xname, repid, repsz)); @@ -183,9 +187,7 @@ ihidev_attach(struct device *parent, struct device *self, void *aux) ihidev_submatch); sc->sc_subdevs[repid] = (struct ihidev *)dev; } - sc->sc_isize += (sc->sc_nrepid != 1); /* one byte for the report ID */ - - sc->sc_ibuf = malloc(sc->sc_isize, M_USBDEV, M_WAITOK); + sc->sc_ibuf = malloc(sc->sc_isize, M_DEVBUF, M_WAITOK); /* register interrupt with system */ if (ia->ia_int > 0) { @@ -417,15 +419,11 @@ ihidev_intr(void *arg) { struct ihidev_softc *sc = arg; struct ihidev *scd; - size_t size, psize; + u_int psize; int res, i; u_char *p; u_int rep = 0; - size = letoh16(sc->hid_desc.wMaxInputLength); - if (size > sc->sc_isize); - size = sc->sc_isize; - iic_acquire_bus(sc->sc_tag, 0); /* XXX: force I2C_F_POLL for now to avoid dwiic interrupting while we @@ -436,7 +434,7 @@ ihidev_intr(void *arg) iic_release_bus(sc->sc_tag, 0); DPRINTF(("%s: ihidev_intr: hid input:", sc->sc_dev.dv_xname)); - for (i = 0; i < size; i++) + for (i = 0; i < sc->sc_isize; i++) DPRINTF((" %.2x", sc->sc_ibuf[i])); DPRINTF(("\n")); @@ -447,9 +445,9 @@ ihidev_intr(void *arg) return (1); } - if (psize > size) { - DPRINTF(("%s: %s: truncated packet (%zu > %zu)\n", - sc->sc_dev.dv_xname, __func__, psize, size)); + if (psize > sc->sc_isize) { + DPRINTF(("%s: %s: truncated packet (%u > %u)\n", + sc->sc_dev.dv_xname, __func__, psize, sc->sc_isize)); return (1); } |