First of all: I send this via sendbug(1) before, but I am not sure if it went i through... So this might be a repost. My apologies for that.
tl;dr: I am afraid that a FAILING RANGE CHECK in a parser is causing FALSE POSITIVES in higher functions. Due to Vendor specific usage pages. In sys/dev/hid/hid.c. The bug I have encountered is in the kernel, more precisely in sys/dev/hid/hid.c, in the function hid_get_item(). It implements a parser for the report descriptors of HID devices. This is necessary, since each one of them has their own data format for reporting events, so one mouse might report movement with 8 bit resolution, others with 16 bit. Some of them might report the X coordinates first, some of them the Y coordinates. The way the HID subsystem of (Open)BSD works is by parsing said report descriptor, and creating its own data structures for parsing the reports later. (Which come in whenever the user is moving the mouse, for example). Complex HID can send out multiple of those reports, some of them with standardized data, some of them with vendor specific one. Each report is distinguished by different report IDs. Since it would not be efficient to describe the report for a keyboard as "key A: 1 bit. key B: 1 bit. key C: 1 bit....", the report descriptor has the possibility of defining "Report Sizes" and "Report Counts". So, essentially, the report descriptor would be more along the lines of "For the keys A-Z, define 1 bit each, 26 times". So, this is the RANGE I was talking about. AND HERE IS THE BUG: In standard scenarios, having a large number of Report Counts does not make sense. Hence, the internal datastructures in struct hid_data stores them in uint8_t variables for them. However, the report descriptor below contains the description for a VENDOR SPECIFIC REPORT, which has report counts of 514 or higher. There is a range check in place already, but what is worrying, is that a higher function is having a FALSE POSITIVE all of a sudden when this part of the report descriptor is being parsed. Namely: imt_find_winptp_reports() in sys/dev/i2c/imt.c is looking for the report which would contain the coordinates reported by the touchpad. With the descriptor below, the correct answer would be the report with the report ID 0x54=84. Instead, it matches report ID 0x06, aka the VENDOR SPECIFIC one. The call tree is imt_find_winptp_reports() -> hid_is_collection() -> hid_get_item() The observable effect is a mildly inconveniant one: I am not able to do two-finger scrolling with my touchpad. However, it would be great if somebody else could have a look to rule out any buffer overrun scenarios inside the OpenBSD kernel. How to replicate: Try to parse the following report descriptor. (679 bytes, MD5: c17523df01eccfd4531d7175e822f9a6) The codes 96 02 02 and 96 00 01 will cause record counts that are too large. The imt_find_winptp_reports() will exit after setting sc->sc_rep_input to 0x06 (wrong) instead of 0x54 (correct). 05 01 09 02 a1 01 85 01 09 01 a1 00 05 09 19 01 29 02 15 00 25 01 75 01 95 02 81 02 95 06 81 03 05 01 09 30 09 31 15 81 25 7f 75 08 95 02 81 06 75 08 95 05 81 03 c0 06 00 ff 09 01 85 0e 09 c5 15 00 26 ff 00 75 08 95 04 b1 02 c0 06 00 ff 09 01 a1 01 85 5c 09 01 95 0b 75 08 81 06 85 0d 09 c5 15 00 26 ff 00 75 08 95 04 b1 02 85 0c 09 c6 96 10 03 75 08 b1 02 85 0b 09 c7 96 02 02 96 02 02 75 08 b1 02 c0 05 0d 09 05 a1 01 85 54 05 09 09 01 15 00 25 01 75 01 95 01 81 02 75 01 95 03 81 03 05 0d 09 54 25 0f 75 04 95 01 81 02 05 0d 09 56 15 00 25 64 55 0c 66 01 10 47 ff ff 00 00 27 ff ff 00 00 75 10 95 01 81 02 05 0d 09 22 a1 02 09 47 09 42 15 00 25 01 75 01 95 02 81 02 75 01 95 02 81 03 09 51 25 0f 75 04 95 01 81 02 05 01 09 30 15 00 26 c8 0d 35 00 46 d4 2b 55 0d 65 11 75 10 95 01 81 02 09 31 26 01 07 46 53 16 46 53 16 81 02 c0 05 0d 09 22 a1 02 09 47 09 42 15 00 25 01 75 01 95 02 81 02 75 01 95 02 81 03 09 51 25 0f 75 04 95 01 81 02 05 01 09 30 15 00 26 c8 0d 35 00 46 d4 2b 55 0d 65 11 75 10 95 01 81 02 09 31 26 01 07 46 53 16 46 53 16 81 02 c0 05 0d 09 22 a1 02 09 47 09 42 15 00 25 01 75 01 95 02 81 02 75 01 95 02 81 03 09 51 25 0f 75 04 95 01 81 02 05 01 09 30 15 00 26 c8 0d 35 00 46 d4 2b 55 0d 65 11 75 10 95 01 81 02 09 31 26 01 07 46 53 16 46 53 16 81 02 c0 05 0d 09 22 a1 02 09 47 09 42 15 00 25 01 75 01 95 02 81 02 75 01 95 02 81 03 09 51 25 0f 75 04 95 01 81 02 05 01 09 30 15 00 26 c8 0d 35 00 46 d4 2b 55 0d 65 11 75 10 95 01 81 02 09 31 26 01 07 46 53 16 46 53 16 81 02 c0 05 0d 09 22 a1 02 09 47 09 42 15 00 25 01 75 01 95 02 81 02 75 01 95 02 81 03 09 51 25 0f 75 04 95 01 81 02 05 01 09 30 15 00 26 c8 0d 35 00 46 d4 2b 55 0d 65 11 75 10 95 01 81 02 09 31 26 01 07 46 53 16 46 53 16 81 02 c0 05 0d 85 02 09 55 09 59 75 04 95 02 25 0f b1 02 85 07 09 60 75 01 95 01 15 00 25 01 b1 02 95 0f b1 03 06 00 ff 06 00 ff 85 06 09 c5 15 00 26 ff 00 75 08 96 00 01 b1 02 c0 05 0d 09 0e a1 01 85 03 09 22 a1 00 09 52 15 00 25 0a 75 10 95 01 b1 02 c0 09 22 a1 00 85 05 09 57 09 58 75 01 95 02 25 01 b1 02 95 0e b1 03 c0 c0 Further read: https://www.usb.org/sites/default/files/documents/hid1_11.pdf https://www.usb.org/sites/default/files/hut1_6.pdf