Skip to content

Commit 953af3c

Browse files
Benjamin Tissoiresgregkh
authored andcommitted
HID: core: ensure __hid_request reserves the report ID as the first byte
commit 0d0777c upstream. The low level transport driver expects the first byte to be the report ID, even when the report ID is not use (in which case they just shift the buffer). However, __hid_request() whas not offsetting the buffer it used by one in this case, meaning that the raw_request() callback emitted by the transport driver would be stripped of the first byte. Note: this changes the API for uhid devices when a request is made through hid_hw_request. However, several considerations makes me think this is fine: - every request to a HID device made through hid_hw_request() would see that change, but every request made through hid_hw_raw_request() already has the new behaviour. So that means that the users are already facing situations where they might have or not the first byte being the null report ID when it is 0. We are making things more straightforward in the end. - uhid is mainly used for BLE devices - uhid is also used for testing, but I don't see that change a big issue - for BLE devices, we can check which kernel module is calling hid_hw_request() - and in those modules, we can check which are using a Bluetooth device - and then we can check if the command is used with a report ID or not. - surprise: none of the kernel module are using a report ID 0 - and finally, bluez, in its function set_report()[0], does the same shift if the report ID is 0 and the given buffer has a size > 0. [0] https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/profiles/input/hog-lib.c#n879 Reported-by: Alan Stern <stern@rowland.harvard.edu> Closes: https://lore.kernel.org/linux-input/c75433e0-9b47-4072-bbe8-b1d14ea97b13@rowland.harvard.edu/ Reported-by: syzbot+8258d5439c49d4c35f43@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=8258d5439c49d4c35f43 Tested-by: syzbot+8258d5439c49d4c35f43@syzkaller.appspotmail.com Fixes: 4fa5a7f ("HID: core: implement generic .request()") Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20250710-report-size-null-v2-2-ccf922b7c4e5@kernel.org Signed-off-by: Benjamin Tissoires <bentiss@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent a262370 commit 953af3c

File tree

1 file changed

+9
-2
lines changed

1 file changed

+9
-2
lines changed

drivers/hid/hid-core.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1966,18 +1966,25 @@ static struct hid_report *hid_get_report(struct hid_report_enum *report_enum,
19661966
int __hid_request(struct hid_device *hid, struct hid_report *report,
19671967
enum hid_class_request reqtype)
19681968
{
1969-
char *buf;
1969+
char *buf, *data_buf;
19701970
int ret;
19711971
u32 len;
19721972

19731973
buf = hid_alloc_report_buf(report, GFP_KERNEL);
19741974
if (!buf)
19751975
return -ENOMEM;
19761976

1977+
data_buf = buf;
19771978
len = hid_report_len(report);
19781979

1980+
if (report->id == 0) {
1981+
/* reserve the first byte for the report ID */
1982+
data_buf++;
1983+
len++;
1984+
}
1985+
19791986
if (reqtype == HID_REQ_SET_REPORT)
1980-
hid_output_report(report, buf);
1987+
hid_output_report(report, data_buf);
19811988

19821989
ret = hid->ll_driver->raw_request(hid, report->id, buf, len,
19831990
report->type, reqtype);

0 commit comments

Comments
 (0)