Correct a buffer overflow in HID report parsing which stopped some mice from working. Also correct some other possible buffer overflows and a parsing error or two. Reference: /n/sources/patch/applied/usbmouse-reportproto Date: Sun Dec 16 00:03:08 CET 2012 Signed-off-by: miller@hamnavoe.com --- /sys/src/cmd/usb/kb/hid.h Thu Dec 13 21:31:33 2012 +++ /sys/src/cmd/usb/kb/hid.h Tue Dec 18 20:53:48 2012 @@ -64,7 +64,7 @@ int kbmain(Dev *d, int argc, char*argv[]); enum{ - MaxChLen = 16, /* bytes */ + MaxChLen = 64, /* bytes */ }; struct Chain { @@ -83,13 +83,13 @@ KindY, KindWheel, - MaxVals = 8, + MaxVals = 16, MaxIfc = 8, }; struct HidInterface { ulong v[MaxVals]; /* one ulong per val should be enough */ - int kind[MaxVals]; + uchar kind[MaxVals]; int nbits; int count; }; @@ -116,10 +116,12 @@ HidPtr = 0x01, HidX = 0x30, HidY = 0x31, + HidZ = 0x32, HidWheel = 0x38, HidInput = 0x81, HidReportId = 0x85, + HidReportIdPtr = 0x01, HidEnd = 0xc0, }; --- /sys/src/cmd/usb/kb/hid.c Thu Dec 13 21:31:38 2012 +++ /sys/src/cmd/usb/kb/hid.c Sat Dec 15 23:59:15 2012 @@ -55,8 +55,8 @@ int parsereportdesc(HidRepTempl *temp, uchar *repdesc, int repsz) { - int i, j, l, n, isptr, hasxy, hasbut, nk, ncoll; - int ks[MaxVals]; + int i, j, l, n, isptr, hasxy, hasbut, nk, ncoll, dsize; + uchar ks[MaxVals+1]; HidInterface *ifs; ifs = temp->ifcs; @@ -66,11 +66,15 @@ n = 0; nk = 0; memset(ifs, 0, sizeof *ifs * MaxIfc); - for(i = 0; i < repsz; i += 2){ + for(i = 0; i < repsz; i += dsize+1){ + dsize = (1 << (repdesc[i] & 03)) >> 1; + if(nk > MaxVals){ + fprint(2, "bad report: too many input types\n"); + return -1; + } if(n == MaxIfc) break; if(repdesc[i] == HidEnd){ - i--; ncoll--; if(ncoll == 0) break; @@ -79,7 +83,7 @@ switch(repdesc[i]){ case HidReportId: switch(repdesc[i+1]){ - case HidReportApp: + case HidReportIdPtr: temp->id = repdesc[i+1]; break; default: @@ -98,6 +102,9 @@ hasxy++; ks[nk++] = KindY; break; + case HidZ: + ks[nk++] = KindPad; + break; case HidWheel: ks[nk++] = KindWheel; break; @@ -121,6 +128,10 @@ ifs[n].count = repdesc[i+1]; break; case HidInput: + if(ifs[n].count > MaxVals){ + fprint(2, "bad report: input count too big\n"); + return -1; + } for(j = 0; j