Ich hab (glaube ich) einen Bug im OpenBSD kernel gefunden. *freu*

dettus

Bicycle User
Gerade an bugs@openbsd.org geschickt.
Mal gucken, wann es durchkommt...

Code:
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. Howver, 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:
 
Habe den Patch getestet. Hier der Output. Ich habe keine Veraenderung bemerkt, aber 2-Finger-Scrolling hat auch vorher schon funktioniert. Der Patch hat jedenfalls nichts bei mir kaputt gemacht. :-) Funktioniert 2-Finger-Scrolling nun bei Dir?

dmesg
Code:
bsdforen> 381 bytes> 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 00 03 75 08 B1 02 85 0B 09 C7 95 82 75 08 B1
02 C0 05 0D 09 05 A1 01 85 04 09 22 A1 02 15 00 25 01 09 47 09 42 95 02 75 01 81
02 75 01 95 02 81 03 95 01 75 04 25 0F 09 51 81 02 05 01 15 00 26 F4 0B 75 10 55
0D 65 11 09 30 35 00 46 02 26 95 01 81 02 46 CD 14 26 85 06 26 85 06 09 31 81 02
05 0D 15 00 25 64 95 03 C0 55 0C 66 01 10 47 FF FF 00 00 27 FF FF 00 00 75 10 95
01 09 56 81 02 09 54 25 7F 95 01 75 08 81 02 05 09 09 01 25 01 75 01 95 01 81 02
95 07 81 03 09 C5 75 08 95 02 81 03 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

EDIT:
Code:
$ sysctl kern.version
kern.version=OpenBSD 7.7-current (CUSTOM) #1: Wed May 21 21:47:02 CEST 2025
    cr@hal.local:/usr/src/sys/arch/amd64/compile/CUSTOM
 
Zurück
Oben