On Mon, May 4, 2026 at 4:48 AM Benjamin Tissoires bentiss@kernel.org wrote:
commit 0a3fe972a7cb ("HID: core: Mitigate potential OOB by removing bogus memset()") enforced the provided data to be at least the size of the declared buffer in the report descriptor to prevent a buffer overflow. However, we can try to be smarter by providing both the buffer size and the data size, meaning that hid_report_raw_event() can make better decision whether we should plaining reject the buffer (buffer overflow attempt) or if we can safely memset it to 0 and pass it to the rest of the stack.
Fixes: 0a3fe972a7cb ("HID: core: Mitigate potential OOB by removing bogus memset()") Cc: stable@vger.kernel.org Signed-off-by: Benjamin Tissoires bentiss@kernel.org
drivers/hid/bpf/hid_bpf_dispatch.c | 6 ++++-- drivers/hid/hid-core.c | 42 +++++++++++++++++++++++++------------- drivers/hid/hid-gfrm.c | 4 ++-- drivers/hid/hid-logitech-hidpp.c | 2 +- drivers/hid/hid-multitouch.c | 2 +- drivers/hid/hid-primax.c | 2 +- drivers/hid/hid-vivaldi-common.c | 2 +- drivers/hid/wacom_sys.c | 6 +++--- drivers/staging/greybus/hid.c | 2 +- include/linux/hid.h | 4 ++-- include/linux/hid_bpf.h | 14 ++++++++----- 11 files changed, 53 insertions(+), 33 deletions(-)
diff --git a/drivers/hid/bpf/hid_bpf_dispatch.c b/drivers/hid/bpf/hid_bpf_dispatch.c index 50c7b45c59e3..d0130658091b 100644 --- a/drivers/hid/bpf/hid_bpf_dispatch.c +++ b/drivers/hid/bpf/hid_bpf_dispatch.c @@ -24,7 +24,8 @@ EXPORT_SYMBOL(hid_ops);
u8 * dispatch_hid_bpf_device_event(struct hid_device *hdev, enum hid_report_type type, u8 *data,
u32 *size, int interrupt, u64 source, bool from_bpf)
size_t *buf_size, u32 *size, int interrupt, u64 source,bool from_bpf){ struct hid_bpf_ctx_kern ctx_kern = { .ctx = { @@ -74,6 +75,7 @@ dispatch_hid_bpf_device_event(struct hid_device *hdev, enum hid_report_type type *size = ret; }
*buf_size = ctx_kern.ctx.allocated_size; return ctx_kern.data;} EXPORT_SYMBOL_GPL(dispatch_hid_bpf_device_event); @@ -505,7 +507,7 @@ __hid_bpf_input_report(struct hid_bpf_ctx *ctx, enum hid_report_type type, u8 *b if (ret) return ret;
return hid_ops->hid_input_report(ctx->hid, type, buf, size, 0, (u64)(long)ctx, true,
return hid_ops->hid_input_report(ctx->hid, type, buf, size, size, 0, (u64)(long)ctx, true, lock_already_taken);}
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 61afec5915ec..a806820df7e5 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -2033,24 +2033,32 @@ int __hid_request(struct hid_device *hid, struct hid_report *report, } EXPORT_SYMBOL_GPL(__hid_request);
-int hid_report_raw_event(struct hid_device *hid, enum hid_report_type type, u8 *data, u32 size,
int interrupt)+int hid_report_raw_event(struct hid_device *hid, enum hid_report_type type, u8 *data,
size_t bufsize, u32 size, int interrupt){ struct hid_report_enum *report_enum = hid->report_enum + type; struct hid_report *report; struct hid_driver *hdrv; int max_buffer_size = HID_MAX_BUFFER_SIZE; u32 rsize, csize = size;
size_t bsize = bufsize; u8 *cdata = data; int ret = 0; report = hid_get_report(report_enum, data); if (!report)
goto out;
return 0;if (unlikely(bsize < csize)) {hid_warn_ratelimited(hid, "Event data for report %d is incorrect (%d vs %ld)\n",report->id, csize, bsize);
This fails to build on 32-bit with this error:
In file included from ./include/linux/device.h:15, from ./include/linux/input.h:19, from drivers/hid/hid-core.c:25: drivers/hid/hid-core.c: In function ‘hid_report_raw_event’: drivers/hid/hid-core.c:2053:43: error: format ‘%ld’ expects argument of type ‘long int’, but argument 5 has type ‘size_t’ {aka ‘unsigned int’} [-Werror=format=] 2053 | hid_warn_ratelimited(hid, "Event data for report %d is incorrect (%d vs %ld)\n", | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The proper format specifier for size_t is "%zu".
Brian Gerst