Module Name: src Committed By: maxv Date: Wed Jan 1 09:40:17 UTC 2020
Modified Files: src/sys/dev/hid: hid.c Log Message: Fix small read overflows when parsing HID tables. Noticed by kASan the other day while I was playing with vHCI. To generate a diff of this commit: cvs rdiff -u -r1.3 -r1.4 src/sys/dev/hid/hid.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/hid/hid.c diff -u src/sys/dev/hid/hid.c:1.3 src/sys/dev/hid/hid.c:1.4 --- src/sys/dev/hid/hid.c:1.3 Thu Nov 15 23:01:45 2018 +++ src/sys/dev/hid/hid.c Wed Jan 1 09:40:17 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: hid.c,v 1.3 2018/11/15 23:01:45 jakllsch Exp $ */ +/* $NetBSD: hid.c,v 1.4 2020/01/01 09:40:17 maxv Exp $ */ /* $FreeBSD: src/sys/dev/usb/hid.c,v 1.11 1999/11/17 22:33:39 n_hibma Exp $ */ /* @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: hid.c,v 1.3 2018/11/15 23:01:45 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: hid.c,v 1.4 2020/01/01 09:40:17 maxv Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" @@ -149,27 +149,33 @@ hid_get_item(struct hid_data *s, struct } for (;;) { p = s->p; - if (p >= s->end) - return 0; + if (p + 1 > s->end) + return 0; bSize = *p++; + if (bSize == 0xfe) { /* long item */ + if (p + 3 > s->end) + return 0; bSize = *p++; bSize |= *p++ << 8; bTag = *p++; - data = p; - p += bSize; bType = 0xff; /* XXX what should it be */ } else { /* short item */ bTag = bSize >> 4; bType = (bSize >> 2) & 3; bSize &= 3; - if (bSize == 3) bSize = 4; - data = p; - p += bSize; + if (bSize == 3) + bSize = 4; } + + data = p; + if (p + bSize > s->end) + return 0; + p += bSize; + s->p = p; switch(bSize) { case 0: