* [PATCH 0/3] HID: core: fix __hid_request when no report ID is used
@ 2025-07-09 14:51 Benjamin Tissoires
2025-07-09 14:51 ` [PATCH 1/3] HID: core: ensure the allocated report buffer can contain the reserved report ID Benjamin Tissoires
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Benjamin Tissoires @ 2025-07-09 14:51 UTC (permalink / raw)
To: Jiri Kosina, Alan Stern
Cc: linux-input, linux-kernel, Benjamin Tissoires, stable,
syzbot+8258d5439c49d4c35f43
[Ideally I'd like to have tests in selftests, but I couldn't extract
them out of the syzbot reproducer, so sending that first series to check
against syzbot]
Followup of https://lore.kernel.org/linux-input/c75433e0-9b47-4072-bbe8-b1d14ea97b13@rowland.harvard.edu/
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 without a local reproducer this
is going to be difficult to implement.
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
---
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(-)
---
base-commit: 1f988d0788f50d8464f957e793fab356e2937369
change-id: 20250709-report-size-null-37619ea20288
Best regards,
--
Benjamin Tissoires <bentiss@kernel.org>
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 1/3] HID: core: ensure the allocated report buffer can contain the reserved report ID
2025-07-09 14:51 [PATCH 0/3] HID: core: fix __hid_request when no report ID is used Benjamin Tissoires
@ 2025-07-09 14:51 ` Benjamin Tissoires
2025-07-09 14:51 ` [PATCH 2/3] HID: core: ensure __hid_request reserves the report ID as the first byte Benjamin Tissoires
2025-07-09 14:51 ` [PATCH 3/3] HID: core: do not bypass hid_hw_raw_request Benjamin Tissoires
2 siblings, 0 replies; 5+ messages in thread
From: Benjamin Tissoires @ 2025-07-09 14:51 UTC (permalink / raw)
To: Jiri Kosina, Alan Stern
Cc: linux-input, linux-kernel, Benjamin Tissoires, stable
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@rowland.harvard.edu/
Cc: stable@vger.kernel.org
Suggested-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
---
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 b348d0464314ca331da073128f0ec4e0a6a91ed1..1a231dd9e4bc83202f2cbcd8b3a21e8c82b9deec 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1883,9 +1883,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.49.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 2/3] HID: core: ensure __hid_request reserves the report ID as the first byte
2025-07-09 14:51 [PATCH 0/3] HID: core: fix __hid_request when no report ID is used Benjamin Tissoires
2025-07-09 14:51 ` [PATCH 1/3] HID: core: ensure the allocated report buffer can contain the reserved report ID Benjamin Tissoires
@ 2025-07-09 14:51 ` Benjamin Tissoires
2025-07-09 14:51 ` [PATCH 3/3] HID: core: do not bypass hid_hw_raw_request Benjamin Tissoires
2 siblings, 0 replies; 5+ messages in thread
From: Benjamin Tissoires @ 2025-07-09 14:51 UTC (permalink / raw)
To: Jiri Kosina, Alan Stern
Cc: linux-input, linux-kernel, Benjamin Tissoires,
syzbot+8258d5439c49d4c35f43, stable
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.
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
Fixes: 4fa5a7f76cc7 ("HID: core: implement generic .request()")
Cc: stable@vger.kernel.org
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
---
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 1a231dd9e4bc83202f2cbcd8b3a21e8c82b9deec..320887c365f7a36f7376556ffd19f99e52b7d732 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1976,7 +1976,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,
enum hid_class_request reqtype)
{
- char *buf;
+ char *buf, *data_buf;
int ret;
u32 len;
@@ -1984,10 +1984,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.49.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 3/3] HID: core: do not bypass hid_hw_raw_request
2025-07-09 14:51 [PATCH 0/3] HID: core: fix __hid_request when no report ID is used Benjamin Tissoires
2025-07-09 14:51 ` [PATCH 1/3] HID: core: ensure the allocated report buffer can contain the reserved report ID Benjamin Tissoires
2025-07-09 14:51 ` [PATCH 2/3] HID: core: ensure __hid_request reserves the report ID as the first byte Benjamin Tissoires
@ 2025-07-09 14:51 ` Benjamin Tissoires
2025-07-09 15:23 ` Alan Stern
2 siblings, 1 reply; 5+ messages in thread
From: Benjamin Tissoires @ 2025-07-09 14:51 UTC (permalink / raw)
To: Jiri Kosina, Alan Stern
Cc: linux-input, linux-kernel, Benjamin Tissoires, stable
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@rowland.harvard.edu/
Cc: stable@vger.kernel.org
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
---
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 320887c365f7a36f7376556ffd19f99e52b7d732..b31b8a2fd540bd5ed66599020824726e69d10d75 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1996,8 +1996,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.49.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 3/3] HID: core: do not bypass hid_hw_raw_request
2025-07-09 14:51 ` [PATCH 3/3] HID: core: do not bypass hid_hw_raw_request Benjamin Tissoires
@ 2025-07-09 15:23 ` Alan Stern
0 siblings, 0 replies; 5+ messages in thread
From: Alan Stern @ 2025-07-09 15:23 UTC (permalink / raw)
To: Benjamin Tissoires; +Cc: Jiri Kosina, linux-input, linux-kernel, stable
On Wed, Jul 09, 2025 at 04:51:48PM +0200, Benjamin Tissoires wrote:
> 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.
Don't worry too much about the sanity checks. If they had been in
place, we wouldn't have learned about the bugs in __hid_request()!
Alan Stern
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2025-07-09 15:23 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-09 14:51 [PATCH 0/3] HID: core: fix __hid_request when no report ID is used Benjamin Tissoires
2025-07-09 14:51 ` [PATCH 1/3] HID: core: ensure the allocated report buffer can contain the reserved report ID Benjamin Tissoires
2025-07-09 14:51 ` [PATCH 2/3] HID: core: ensure __hid_request reserves the report ID as the first byte Benjamin Tissoires
2025-07-09 14:51 ` [PATCH 3/3] HID: core: do not bypass hid_hw_raw_request Benjamin Tissoires
2025-07-09 15:23 ` Alan Stern
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).