[PATCH OLK-5.10 0/3] HID: core: fix __hid_request when no report ID is used

New version (unchanged for patches 1-3), with a test added so we can detect this. Followup of https://lore.kernel.org/linux-input/c75433e0-9b47-4072-bbe8-b1d14ea97b13@row... This initial series attempt at fixing the various bugs discovered by Alan regarding __hid_request(). Syzbot managed to create a report descriptor which presents a feature request of size 0 (still trying to extract it) and this exposed the fact that __hid_request() was incorrectly handling the case when the report ID is not used. Send a first batch of fixes now so we get the feedback from syzbot ASAP. Note: in the series, I also mentioned that the report of size 0 should be stripped out of the HID device, but I'm not entirely sure this would be a good idea in the end. Signed-off-by: Benjamin Tissoires <bentiss@kernel.org> Signed-off-by: Pan Taixi <pantaixi1@huawei.com> Benjamin Tissoires (3): HID: core: ensure the allocated report buffer can contain the reserved report ID HID: core: ensure __hid_request reserves the report ID as the first byte HID: core: do not bypass hid_hw_raw_request drivers/hid/hid-core.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) -- 2.34.1

From: Benjamin Tissoires <bentiss@kernel.org> mainline inclusion from mainline-v6.16-rc7 commit 4f15ee98304b96e164ff2340e1dfd6181c3f42aa category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/ICPD1U CVE: CVE-2025-38495 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=... -------------------------------- When the report ID is not used, the low level transport drivers expect the first byte to be 0. However, currently the allocated buffer not account for that extra byte, meaning that instead of having 8 guaranteed bytes for implement to be working, we only have 7. Reported-by: Alan Stern <stern@rowland.harvard.edu> Closes: https://lore.kernel.org/linux-input/c75433e0-9b47-4072-bbe8-b1d14ea97b13@row... Cc: stable@vger.kernel.org Suggested-by: Alan Stern <stern@rowland.harvard.edu> Link: https://patch.msgid.link/20250710-report-size-null-v2-1-ccf922b7c4e5@kernel.... Signed-off-by: Benjamin Tissoires <bentiss@kernel.org> Signed-off-by: Pan Taixi <pantaixi1@huawei.com> --- drivers/hid/hid-core.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 0fef4bdb90f1..58b9e71ea78f 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1660,9 +1660,12 @@ u8 *hid_alloc_report_buf(struct hid_report *report, gfp_t flags) /* * 7 extra bytes are necessary to achieve proper functionality * of implement() working on 8 byte chunks + * 1 extra byte for the report ID if it is null (not used) so + * we can reserve that extra byte in the first position of the buffer + * when sending it to .raw_request() */ - u32 len = hid_report_len(report) + 7; + u32 len = hid_report_len(report) + 7 + (report->id == 0); return kzalloc(len, flags); } -- 2.34.1

From: Benjamin Tissoires <bentiss@kernel.org> mainline inclusion from mainline-v6.16-rc7 commit 0d0777ccaa2d46609d05b66ba0096802a2746193 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/ICPD1U CVE: CVE-2025-38495 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=... -------------------------------- 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-l... Reported-by: Alan Stern <stern@rowland.harvard.edu> Closes: https://lore.kernel.org/linux-input/c75433e0-9b47-4072-bbe8-b1d14ea97b13@row... Reported-by: syzbot+8258d5439c49d4c35f43@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=8258d5439c49d4c35f43 Tested-by: syzbot+8258d5439c49d4c35f43@syzkaller.appspotmail.com Fixes: 4fa5a7f76cc7 ("HID: core: implement generic .request()") Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20250710-report-size-null-v2-2-ccf922b7c4e5@kernel.... Signed-off-by: Benjamin Tissoires <bentiss@kernel.org> Conflicts: drivers/hid/hid-core.c [ Context conflicts due to 735e1bb1b806 ("HID: convert defines of HID class requests into a proper enum") not merged, which refactored int reqtype to enum hid_class_request reqtype ] Signed-off-by: Pan Taixi <pantaixi1@huawei.com> --- drivers/hid/hid-core.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 58b9e71ea78f..51fcc6c205b6 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1728,7 +1728,7 @@ static struct hid_report *hid_get_report(struct hid_report_enum *report_enum, int __hid_request(struct hid_device *hid, struct hid_report *report, int reqtype) { - char *buf; + char *buf, *data_buf; int ret; u32 len; @@ -1736,10 +1736,17 @@ int __hid_request(struct hid_device *hid, struct hid_report *report, if (!buf) return -ENOMEM; + data_buf = buf; len = hid_report_len(report); + if (report->id == 0) { + /* reserve the first byte for the report ID */ + data_buf++; + len++; + } + if (reqtype == HID_REQ_SET_REPORT) - hid_output_report(report, buf); + hid_output_report(report, data_buf); ret = hid->ll_driver->raw_request(hid, report->id, buf, len, report->type, reqtype); -- 2.34.1

From: Benjamin Tissoires <bentiss@kernel.org> mainline inclusion from mainline-v6.16-rc7 commit c2ca42f190b6714d6c481dfd3d9b62ea091c946b category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/ICPD1U CVE: CVE-2025-38495 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=... -------------------------------- hid_hw_raw_request() is actually useful to ensure the provided buffer and length are valid. Directly calling in the low level transport driver function bypassed those checks and allowed invalid paramto be used. Reported-by: Alan Stern <stern@rowland.harvard.edu> Closes: https://lore.kernel.org/linux-input/c75433e0-9b47-4072-bbe8-b1d14ea97b13@row... Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20250710-report-size-null-v2-3-ccf922b7c4e5@kernel.... Signed-off-by: Benjamin Tissoires <bentiss@kernel.org> Signed-off-by: Pan Taixi <pantaixi1@huawei.com> --- drivers/hid/hid-core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 51fcc6c205b6..3094c33bb8f9 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1748,8 +1748,7 @@ int __hid_request(struct hid_device *hid, struct hid_report *report, if (reqtype == HID_REQ_SET_REPORT) hid_output_report(report, data_buf); - ret = hid->ll_driver->raw_request(hid, report->id, buf, len, - report->type, reqtype); + ret = hid_hw_raw_request(hid, report->id, buf, len, report->type, reqtype); if (ret < 0) { dbg_hid("unable to complete request: %d\n", ret); goto out; -- 2.34.1

反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://gitee.com/openeuler/kernel/pulls/17480 邮件列表地址:https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/NTE... FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://gitee.com/openeuler/kernel/pulls/17480 Mailing list address: https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/NTE...
participants (2)
-
Pan Taixi
-
patchwork bot