Re: [PATCH v3 1/4] HID: pass the buffer size to hid_report_raw_event
From: Brian Gerst
Date: Sat May 16 2026 - 14:25:46 EST
On Mon, May 4, 2026 at 4:48 AM Benjamin Tissoires <bentiss@xxxxxxxxxx> 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@xxxxxxxxxxxxxxx
> Signed-off-by: Benjamin Tissoires <bentiss@xxxxxxxxxx>
> ---
> 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