* [PATCH bpf-next 0/2] HID: bpf: Fix hid_bpf_get_data() range check
@ 2026-06-16 16:35 Yiyang Chen
2026-06-16 16:35 ` [PATCH bpf-next 1/2] " Yiyang Chen
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Yiyang Chen @ 2026-06-16 16:35 UTC (permalink / raw)
To: Jiri Kosina, Benjamin Tissoires, bpf, linux-input
Cc: Yiyang Chen, Shuah Khan, Alexei Starovoitov, Daniel Borkmann,
Andrii Nakryiko, Martin KaFai Lau, Eduard Zingerman,
Kumar Kartikeya Dwivedi, Song Liu, Yonghong Song, Jiri Olsa,
linux-kselftest, linux-kernel
hid_bpf_get_data() exposes a pointer into the HID-BPF context data when
the caller-provided offset and size fit inside ctx->allocated_size.
The helper currently checks that range with:
rdwr_buf_size + offset > ctx->allocated_size
Since both operands are unsigned, a very large size can wrap the sum and
make an out-of-range request look valid.
Patch 1 changes the helper to reject offset values beyond the allocation
and then compare the requested size against the remaining bytes.
Patch 2 adds a HID-BPF regression check that asks hid_bpf_get_data() for
offset 2 and size ~0ULL from an rdesc_fixup callback and expects NULL.
It also adds KHDR_INCLUDES to the HID selftest build so the userspace
test sees current kernel UAPI HID definitions.
Validation, rebased and tested on bpf-next master e4287bf34f97
("selftests/bpf: Work around llvm stack overflow in crypto progs"):
git diff --check origin/master..HEAD: OK
scripts/checkpatch.pl --strict -g origin/master..HEAD: OK
make O=/root/ebpf-verifier-bug-detection/kernel-build/bpf-next-hidbpf-20260616 \
drivers/hid/bpf/hid_bpf_dispatch.o: OK
make -C tools/testing/selftests/hid \
O=/root/ebpf-verifier-bug-detection/kernel-build/bpf-next-hidbpf-20260616 \
OUTPUT=/tmp/hid-selftest-026 \
VMLINUX_BTF=/root/ebpf-verifier-bug-detection/kernel-build/bpf-next-hidbpf-20260616/vmlinux \
KHDR_INCLUDES=-isystem /root/ebpf-verifier-bug-detection/kernel-build/bpf-next-hidbpf-20260616/usr/include \
hid_bpf: OK
The sanitized UAPI headers were generated in the build tree with
headers_install. The final install/copy step reported missing rsync in
this environment, but the generated build-tree usr/include was present
and used for the selftest build.
Yiyang Chen (2):
HID: bpf: Fix hid_bpf_get_data() range check
selftests/hid: Cover hid_bpf_get_data() size overflow
drivers/hid/bpf/hid_bpf_dispatch.c | 3 ++-
tools/testing/selftests/hid/Makefile | 2 +-
tools/testing/selftests/hid/hid_bpf.c | 11 +++++++++++
tools/testing/selftests/hid/progs/hid.c | 18 ++++++++++++++++++
4 files changed, 32 insertions(+), 2 deletions(-)
base-commit: e4287bf34f97a88c7d9322f5bde828724c073a6b
--
2.34.1
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH bpf-next 1/2] HID: bpf: Fix hid_bpf_get_data() range check
2026-06-16 16:35 [PATCH bpf-next 0/2] HID: bpf: Fix hid_bpf_get_data() range check Yiyang Chen
@ 2026-06-16 16:35 ` Yiyang Chen
2026-06-16 17:18 ` bot+bpf-ci
2026-06-16 22:52 ` Emil Tsalapatis
2026-06-16 16:35 ` [PATCH bpf-next 2/2] selftests/hid: Cover hid_bpf_get_data() size overflow Yiyang Chen
2026-06-20 14:22 ` [PATCH bpf-next v2 0/2] HID: bpf: Fix hid_bpf_get_data() range check Yiyang Chen
2 siblings, 2 replies; 10+ messages in thread
From: Yiyang Chen @ 2026-06-16 16:35 UTC (permalink / raw)
To: Jiri Kosina, Benjamin Tissoires, bpf, linux-input
Cc: Yiyang Chen, Shuah Khan, Alexei Starovoitov, Daniel Borkmann,
Andrii Nakryiko, Martin KaFai Lau, Eduard Zingerman,
Kumar Kartikeya Dwivedi, Song Liu, Yonghong Song, Jiri Olsa,
linux-kselftest, linux-kernel
hid_bpf_get_data() returns a pointer into the HID-BPF context data when
the caller-provided offset and size fit inside ctx->allocated_size.
The current check adds rdwr_buf_size and offset before comparing the
result against ctx->allocated_size. Since both values are unsigned, a
very large size can wrap the sum below ctx->allocated_size and make the
helper return a pointer even though the requested range is not contained
in the backing buffer.
Use a non-wrapping range check instead: reject offsets beyond the
allocation, then compare the requested size with the remaining bytes
after the offset.
Fixes: 4171954f56fb ("HID: bpf/dispatch: regroup kfuncs definitions")
Signed-off-by: Yiyang Chen <chenyy23@mails.tsinghua.edu.cn>
---
drivers/hid/bpf/hid_bpf_dispatch.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/hid/bpf/hid_bpf_dispatch.c b/drivers/hid/bpf/hid_bpf_dispatch.c
index d0130658091b0..09b45c40d84f0 100644
--- a/drivers/hid/bpf/hid_bpf_dispatch.c
+++ b/drivers/hid/bpf/hid_bpf_dispatch.c
@@ -299,7 +299,8 @@ hid_bpf_get_data(struct hid_bpf_ctx *ctx, unsigned int offset, const size_t rdwr
ctx_kern = container_of(ctx, struct hid_bpf_ctx_kern, ctx);
- if (rdwr_buf_size + offset > ctx->allocated_size)
+ if (offset > ctx->allocated_size ||
+ rdwr_buf_size > ctx->allocated_size - offset)
return NULL;
return ctx_kern->data + offset;
--
2.34.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH bpf-next 2/2] selftests/hid: Cover hid_bpf_get_data() size overflow
2026-06-16 16:35 [PATCH bpf-next 0/2] HID: bpf: Fix hid_bpf_get_data() range check Yiyang Chen
2026-06-16 16:35 ` [PATCH bpf-next 1/2] " Yiyang Chen
@ 2026-06-16 16:35 ` Yiyang Chen
2026-06-16 23:03 ` Emil Tsalapatis
2026-06-20 14:22 ` [PATCH bpf-next v2 0/2] HID: bpf: Fix hid_bpf_get_data() range check Yiyang Chen
2 siblings, 1 reply; 10+ messages in thread
From: Yiyang Chen @ 2026-06-16 16:35 UTC (permalink / raw)
To: Jiri Kosina, Benjamin Tissoires, bpf, linux-input
Cc: Yiyang Chen, Shuah Khan, Alexei Starovoitov, Daniel Borkmann,
Andrii Nakryiko, Martin KaFai Lau, Eduard Zingerman,
Kumar Kartikeya Dwivedi, Song Liu, Yonghong Song, Jiri Olsa,
linux-kselftest, linux-kernel
Add a HID-BPF regression check for hid_bpf_get_data() requests whose
size would overflow when added to the offset.
The new rdesc fixup callback asks for offset 2 and size ~0ULL, then
records whether the helper returns NULL. A vulnerable kernel returns a
non-NULL pointer because the runtime check wraps the addition. A fixed
kernel rejects the request. The test only checks the helper result and
does not dereference the returned pointer.
Also add KHDR_INCLUDES to the HID selftest build so hid_bpf.c sees the
current kernel UAPI HID definitions on systems whose installed headers do
not provide enum hid_report_type.
Signed-off-by: Yiyang Chen <chenyy23@mails.tsinghua.edu.cn>
---
tools/testing/selftests/hid/Makefile | 2 +-
tools/testing/selftests/hid/hid_bpf.c | 11 +++++++++++
tools/testing/selftests/hid/progs/hid.c | 18 ++++++++++++++++++
3 files changed, 30 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/hid/Makefile b/tools/testing/selftests/hid/Makefile
index 50ec9e0406aba..357c6eb5ff5ee 100644
--- a/tools/testing/selftests/hid/Makefile
+++ b/tools/testing/selftests/hid/Makefile
@@ -24,7 +24,7 @@ CXX ?= $(CROSS_COMPILE)g++
HOSTPKG_CONFIG := pkg-config
-CFLAGS += -g -O0 -rdynamic -Wall -Werror -I$(OUTPUT)
+CFLAGS += -g -O0 -rdynamic -Wall -Werror -I$(OUTPUT) $(KHDR_INCLUDES)
CFLAGS += -I$(OUTPUT)/tools/include
LDLIBS += -lelf -lz -lrt -lpthread
diff --git a/tools/testing/selftests/hid/hid_bpf.c b/tools/testing/selftests/hid/hid_bpf.c
index 1e979fb3542ba..f0a210900e63d 100644
--- a/tools/testing/selftests/hid/hid_bpf.c
+++ b/tools/testing/selftests/hid/hid_bpf.c
@@ -887,6 +887,17 @@ TEST_F(hid_bpf, test_rdesc_fixup)
ASSERT_EQ(rpt_desc.value[4], 0x42);
}
+TEST_F(hid_bpf, test_rdesc_fixup_get_data_overflow)
+{
+ const struct test_program progs[] = {
+ { .name = "hid_rdesc_fixup_get_data_overflow" },
+ };
+
+ LOAD_PROGRAMS(progs);
+
+ ASSERT_EQ(self->skel->bss->get_data_overflow_check, 1);
+}
+
static int libbpf_print_fn(enum libbpf_print_level level,
const char *format, va_list args)
{
diff --git a/tools/testing/selftests/hid/progs/hid.c b/tools/testing/selftests/hid/progs/hid.c
index 5ecc845ef7921..c6ae2cd045b0e 100644
--- a/tools/testing/selftests/hid/progs/hid.c
+++ b/tools/testing/selftests/hid/progs/hid.c
@@ -13,6 +13,7 @@ struct attach_prog_args {
__u64 callback_check = 52;
__u64 callback2_check = 52;
+__u64 get_data_overflow_check;
SEC("?struct_ops/hid_device_event")
int BPF_PROG(hid_first_event, struct hid_bpf_ctx *hid_ctx, enum hid_report_type type)
@@ -240,6 +241,23 @@ struct hid_bpf_ops rdesc_fixup = {
.hid_rdesc_fixup = (void *)hid_rdesc_fixup,
};
+SEC("?struct_ops.s/hid_rdesc_fixup")
+int BPF_PROG(hid_rdesc_fixup_get_data_overflow, struct hid_bpf_ctx *hid_ctx)
+{
+ __u8 *data;
+
+ data = hid_bpf_get_data(hid_ctx, 2 /* offset */, ~0ULL /* size */);
+ if (!data)
+ get_data_overflow_check = 1;
+
+ return 0;
+}
+
+SEC(".struct_ops.link")
+struct hid_bpf_ops rdesc_fixup_get_data_overflow = {
+ .hid_rdesc_fixup = (void *)hid_rdesc_fixup_get_data_overflow,
+};
+
SEC("?struct_ops/hid_device_event")
int BPF_PROG(hid_test_insert1, struct hid_bpf_ctx *hid_ctx, enum hid_report_type type)
{
--
2.34.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH bpf-next 1/2] HID: bpf: Fix hid_bpf_get_data() range check
2026-06-16 16:35 ` [PATCH bpf-next 1/2] " Yiyang Chen
@ 2026-06-16 17:18 ` bot+bpf-ci
2026-06-16 22:52 ` Emil Tsalapatis
1 sibling, 0 replies; 10+ messages in thread
From: bot+bpf-ci @ 2026-06-16 17:18 UTC (permalink / raw)
To: chenyy23, jikos, bentiss, bpf, linux-input
Cc: chenyy23, shuah, ast, daniel, andrii, martin.lau, eddyz87, memxor,
song, yonghong.song, jolsa, linux-kselftest, linux-kernel, ast,
andrii, daniel, martin.lau, eddyz87, yonghong.song, clm,
ihor.solodrai
[-- Attachment #1: Type: text/plain, Size: 2523 bytes --]
> commit 7c433bf4ab2de03b77e22dbd3984e39a386997a2
> Author: Yiyang Chen <chenyy23@mails.tsinghua.edu.cn>
> Date: Tue Jun 16 16:35:06 2026 +0000
>
> HID: bpf: Fix hid_bpf_get_data() range check
>
> hid_bpf_get_data() returns a pointer into the HID-BPF context data when
> the caller-provided offset and size fit inside ctx->allocated_size.
>
> The current check adds rdwr_buf_size and offset before comparing the
> result against ctx->allocated_size. Since both values are unsigned, a
> very large size can wrap the sum below ctx->allocated_size and make the
> helper return a pointer even though the requested range is not contained
> in the backing buffer.
>
> Use a non-wrapping range check instead: reject offsets beyond the
> allocation, then compare the requested size with the remaining bytes
> after the offset.
>
> Fixes: 4171954f56fb ("HID: bpf/dispatch: regroup kfuncs definitions")
> Signed-off-by: Yiyang Chen <chenyy23@mails.tsinghua.edu.cn>
The Fixes tag points to commit 4171954f56fb, but that commit only moved
hid_bpf_get_data() without changing its logic. Its commit message states
"No code change, just move down the hid_bpf_get_data() kfunc definition".
The vulnerable addition pattern 'rdwr_buf_size + offset > ctx->allocated_size'
was actually introduced in commit 658ee5a64fcf ("HID: bpf: allocate data
memory for device_event BPF programs"), which changed the field from ctx->size
to ctx->allocated_size while keeping the same overflow-prone check.
Should the Fixes tag reference the commit that introduced the buggy code:
Fixes: 658ee5a64fcf ("HID: bpf: allocate data memory for device_event BPF programs")
> diff --git a/drivers/hid/bpf/hid_bpf_dispatch.c b/drivers/hid/bpf/hid_bpf_dispatch.c
> index d0130658091b..09b45c40d84f 100644
> --- a/drivers/hid/bpf/hid_bpf_dispatch.c
> +++ b/drivers/hid/bpf/hid_bpf_dispatch.c
> @@ -299,7 +299,8 @@ hid_bpf_get_data(struct hid_bpf_ctx *ctx, unsigned int offset, const size_t rdwr
>
> ctx_kern = container_of(ctx, struct hid_bpf_ctx_kern, ctx);
>
> - if (rdwr_buf_size + offset > ctx->allocated_size)
> + if (offset > ctx->allocated_size ||
> + rdwr_buf_size > ctx->allocated_size - offset)
> return NULL;
>
> return ctx_kern->data + offset;
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/27633665618
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH bpf-next 1/2] HID: bpf: Fix hid_bpf_get_data() range check
2026-06-16 16:35 ` [PATCH bpf-next 1/2] " Yiyang Chen
2026-06-16 17:18 ` bot+bpf-ci
@ 2026-06-16 22:52 ` Emil Tsalapatis
1 sibling, 0 replies; 10+ messages in thread
From: Emil Tsalapatis @ 2026-06-16 22:52 UTC (permalink / raw)
To: Yiyang Chen, Jiri Kosina, Benjamin Tissoires, bpf, linux-input
Cc: Shuah Khan, Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Martin KaFai Lau, Eduard Zingerman, Kumar Kartikeya Dwivedi,
Song Liu, Yonghong Song, Jiri Olsa, linux-kselftest, linux-kernel
On Tue Jun 16, 2026 at 12:35 PM EDT, Yiyang Chen wrote:
> hid_bpf_get_data() returns a pointer into the HID-BPF context data when
> the caller-provided offset and size fit inside ctx->allocated_size.
>
> The current check adds rdwr_buf_size and offset before comparing the
> result against ctx->allocated_size. Since both values are unsigned, a
> very large size can wrap the sum below ctx->allocated_size and make the
> helper return a pointer even though the requested range is not contained
> in the backing buffer.
>
> Use a non-wrapping range check instead: reject offsets beyond the
> allocation, then compare the requested size with the remaining bytes
> after the offset.
>
Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com>
> Fixes: 4171954f56fb ("HID: bpf/dispatch: regroup kfuncs definitions")
> Signed-off-by: Yiyang Chen <chenyy23@mails.tsinghua.edu.cn>
> ---
> drivers/hid/bpf/hid_bpf_dispatch.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/hid/bpf/hid_bpf_dispatch.c b/drivers/hid/bpf/hid_bpf_dispatch.c
> index d0130658091b0..09b45c40d84f0 100644
> --- a/drivers/hid/bpf/hid_bpf_dispatch.c
> +++ b/drivers/hid/bpf/hid_bpf_dispatch.c
> @@ -299,7 +299,8 @@ hid_bpf_get_data(struct hid_bpf_ctx *ctx, unsigned int offset, const size_t rdwr
>
> ctx_kern = container_of(ctx, struct hid_bpf_ctx_kern, ctx);
>
> - if (rdwr_buf_size + offset > ctx->allocated_size)
> + if (offset > ctx->allocated_size ||
> + rdwr_buf_size > ctx->allocated_size - offset)
> return NULL;
>
> return ctx_kern->data + offset;
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH bpf-next 2/2] selftests/hid: Cover hid_bpf_get_data() size overflow
2026-06-16 16:35 ` [PATCH bpf-next 2/2] selftests/hid: Cover hid_bpf_get_data() size overflow Yiyang Chen
@ 2026-06-16 23:03 ` Emil Tsalapatis
0 siblings, 0 replies; 10+ messages in thread
From: Emil Tsalapatis @ 2026-06-16 23:03 UTC (permalink / raw)
To: Yiyang Chen, Jiri Kosina, Benjamin Tissoires, bpf, linux-input
Cc: Shuah Khan, Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Martin KaFai Lau, Eduard Zingerman, Kumar Kartikeya Dwivedi,
Song Liu, Yonghong Song, Jiri Olsa, linux-kselftest, linux-kernel
On Tue Jun 16, 2026 at 12:35 PM EDT, Yiyang Chen wrote:
> Add a HID-BPF regression check for hid_bpf_get_data() requests whose
> size would overflow when added to the offset.
>
> The new rdesc fixup callback asks for offset 2 and size ~0ULL, then
> records whether the helper returns NULL. A vulnerable kernel returns a
> non-NULL pointer because the runtime check wraps the addition. A fixed
> kernel rejects the request. The test only checks the helper result and
> does not dereference the returned pointer.
>
> Also add KHDR_INCLUDES to the HID selftest build so hid_bpf.c sees the
> current kernel UAPI HID definitions on systems whose installed headers do
> not provide enum hid_report_type.
>
> Signed-off-by: Yiyang Chen <chenyy23@mails.tsinghua.edu.cn>
> ---
> tools/testing/selftests/hid/Makefile | 2 +-
> tools/testing/selftests/hid/hid_bpf.c | 11 +++++++++++
> tools/testing/selftests/hid/progs/hid.c | 18 ++++++++++++++++++
> 3 files changed, 30 insertions(+), 1 deletion(-)
>
> diff --git a/tools/testing/selftests/hid/Makefile b/tools/testing/selftests/hid/Makefile
> index 50ec9e0406aba..357c6eb5ff5ee 100644
> --- a/tools/testing/selftests/hid/Makefile
> +++ b/tools/testing/selftests/hid/Makefile
> @@ -24,7 +24,7 @@ CXX ?= $(CROSS_COMPILE)g++
>
> HOSTPKG_CONFIG := pkg-config
>
> -CFLAGS += -g -O0 -rdynamic -Wall -Werror -I$(OUTPUT)
> +CFLAGS += -g -O0 -rdynamic -Wall -Werror -I$(OUTPUT) $(KHDR_INCLUDES)
> CFLAGS += -I$(OUTPUT)/tools/include
>
> LDLIBS += -lelf -lz -lrt -lpthread
> diff --git a/tools/testing/selftests/hid/hid_bpf.c b/tools/testing/selftests/hid/hid_bpf.c
> index 1e979fb3542ba..f0a210900e63d 100644
> --- a/tools/testing/selftests/hid/hid_bpf.c
> +++ b/tools/testing/selftests/hid/hid_bpf.c
> @@ -887,6 +887,17 @@ TEST_F(hid_bpf, test_rdesc_fixup)
> ASSERT_EQ(rpt_desc.value[4], 0x42);
> }
>
> +TEST_F(hid_bpf, test_rdesc_fixup_get_data_overflow)
> +{
> + const struct test_program progs[] = {
> + { .name = "hid_rdesc_fixup_get_data_overflow" },
> + };
> +
> + LOAD_PROGRAMS(progs);
> +
> + ASSERT_EQ(self->skel->bss->get_data_overflow_check, 1);
Can you just use the return value of the method? Why the separate
variable?
> +}
> +
> static int libbpf_print_fn(enum libbpf_print_level level,
> const char *format, va_list args)
> {
> diff --git a/tools/testing/selftests/hid/progs/hid.c b/tools/testing/selftests/hid/progs/hid.c
> index 5ecc845ef7921..c6ae2cd045b0e 100644
> --- a/tools/testing/selftests/hid/progs/hid.c
> +++ b/tools/testing/selftests/hid/progs/hid.c
> @@ -13,6 +13,7 @@ struct attach_prog_args {
>
> __u64 callback_check = 52;
> __u64 callback2_check = 52;
> +__u64 get_data_overflow_check;
>
> SEC("?struct_ops/hid_device_event")
> int BPF_PROG(hid_first_event, struct hid_bpf_ctx *hid_ctx, enum hid_report_type type)
> @@ -240,6 +241,23 @@ struct hid_bpf_ops rdesc_fixup = {
> .hid_rdesc_fixup = (void *)hid_rdesc_fixup,
> };
>
> +SEC("?struct_ops.s/hid_rdesc_fixup")
> +int BPF_PROG(hid_rdesc_fixup_get_data_overflow, struct hid_bpf_ctx *hid_ctx)
> +{
> + __u8 *data;
> +
> + data = hid_bpf_get_data(hid_ctx, 2 /* offset */, ~0ULL /* size */);
> + if (!data)
> + get_data_overflow_check = 1;
> +
> + return 0;
> +}
> +
> +SEC(".struct_ops.link")
> +struct hid_bpf_ops rdesc_fixup_get_data_overflow = {
> + .hid_rdesc_fixup = (void *)hid_rdesc_fixup_get_data_overflow,
> +};
> +
> SEC("?struct_ops/hid_device_event")
> int BPF_PROG(hid_test_insert1, struct hid_bpf_ctx *hid_ctx, enum hid_report_type type)
> {
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH bpf-next v2 0/2] HID: bpf: Fix hid_bpf_get_data() range check
2026-06-16 16:35 [PATCH bpf-next 0/2] HID: bpf: Fix hid_bpf_get_data() range check Yiyang Chen
2026-06-16 16:35 ` [PATCH bpf-next 1/2] " Yiyang Chen
2026-06-16 16:35 ` [PATCH bpf-next 2/2] selftests/hid: Cover hid_bpf_get_data() size overflow Yiyang Chen
@ 2026-06-20 14:22 ` Yiyang Chen
2026-06-20 14:22 ` [PATCH bpf-next v2 1/2] " Yiyang Chen
2026-06-20 14:22 ` [PATCH bpf-next v2 2/2] selftests/hid: Cover hid_bpf_get_data() size overflow Yiyang Chen
2 siblings, 2 replies; 10+ messages in thread
From: Yiyang Chen @ 2026-06-20 14:22 UTC (permalink / raw)
To: Jiri Kosina, Benjamin Tissoires, bpf, linux-input
Cc: Yiyang Chen, Shuah Khan, Alexei Starovoitov, Daniel Borkmann,
Andrii Nakryiko, Martin KaFai Lau, Eduard Zingerman,
Kumar Kartikeya Dwivedi, Song Liu, Yonghong Song, Jiri Olsa,
linux-kselftest, linux-kernel
hid_bpf_get_data() exposes a pointer into the HID-BPF context data when
the caller-provided offset and size fit inside ctx->allocated_size.
The helper currently checks that range with:
rdwr_buf_size + offset > ctx->allocated_size
Since both operands are unsigned, a very large size can wrap the sum and
make an out-of-range request look valid.
Patch 1 changes the helper to reject offset values beyond the allocation
and then compare the requested size against the remaining bytes.
Patch 2 adds a HID-BPF regression check that asks hid_bpf_get_data() for
offset 2 and size ~0ULL from an rdesc_fixup callback and expects NULL.
It also adds KHDR_INCLUDES to the HID selftest build so the userspace
test sees current kernel UAPI HID definitions.
Validation, rebased and tested on bpf-next master e4287bf34f97
("selftests/bpf: Work around llvm stack overflow in crypto progs"):
git diff --check e4287bf34f97..HEAD: OK
scripts/checkpatch.pl --strict -g e4287bf34f97..HEAD: OK
make O=/root/ebpf-verifier-bug-detection/kernel-build/bpf-next-hidbpf-20260616 \
drivers/hid/bpf/hid_bpf_dispatch.o: OK
make -C tools/testing/selftests/hid \
O=/root/ebpf-verifier-bug-detection/kernel-build/bpf-next-hidbpf-20260616 \
OUTPUT=/tmp/hid-selftest-026-v2 \
VMLINUX_BTF=/root/ebpf-verifier-bug-detection/kernel-build/bpf-next-hidbpf-20260616/vmlinux \
KHDR_INCLUDES=-isystem /root/ebpf-verifier-bug-detection/kernel-build/bpf-next-hidbpf-20260616/usr/include \
hid_bpf: OK
Changes in v2:
- Drop the temporary data variable around the overflow
hid_bpf_get_data() call in the selftest callback.
- Correct the Fixes tag to commit 658ee5a64fcf ("HID: bpf: allocate
data memory for device_event BPF programs").
v1: https://lore.kernel.org/bpf/cover.1781627122.git.chenyy23@mails.tsinghua.edu.cn/
Yiyang Chen (2):
HID: bpf: Fix hid_bpf_get_data() range check
selftests/hid: Cover hid_bpf_get_data() size overflow
drivers/hid/bpf/hid_bpf_dispatch.c | 3 ++-
tools/testing/selftests/hid/Makefile | 2 +-
tools/testing/selftests/hid/hid_bpf.c | 11 +++++++++++
tools/testing/selftests/hid/progs/hid.c | 15 +++++++++++++++
4 files changed, 29 insertions(+), 2 deletions(-)
base-commit: e4287bf34f97a88c7d9322f5bde828724c073a6b
--
2.34.1
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH bpf-next v2 1/2] HID: bpf: Fix hid_bpf_get_data() range check
2026-06-20 14:22 ` [PATCH bpf-next v2 0/2] HID: bpf: Fix hid_bpf_get_data() range check Yiyang Chen
@ 2026-06-20 14:22 ` Yiyang Chen
2026-06-20 14:22 ` [PATCH bpf-next v2 2/2] selftests/hid: Cover hid_bpf_get_data() size overflow Yiyang Chen
1 sibling, 0 replies; 10+ messages in thread
From: Yiyang Chen @ 2026-06-20 14:22 UTC (permalink / raw)
To: Jiri Kosina, Benjamin Tissoires, bpf, linux-input
Cc: Yiyang Chen, Shuah Khan, Alexei Starovoitov, Daniel Borkmann,
Andrii Nakryiko, Martin KaFai Lau, Eduard Zingerman,
Kumar Kartikeya Dwivedi, Song Liu, Yonghong Song, Jiri Olsa,
linux-kselftest, linux-kernel
hid_bpf_get_data() returns a pointer into the HID-BPF context data when
the caller-provided offset and size fit inside ctx->allocated_size.
The current check adds rdwr_buf_size and offset before comparing the
result against ctx->allocated_size. Since both values are unsigned, a
very large size can wrap the sum below ctx->allocated_size and make the
helper return a pointer even though the requested range is not contained
in the backing buffer.
Use a non-wrapping range check instead: reject offsets beyond the
allocation, then compare the requested size with the remaining bytes
after the offset.
Fixes: 658ee5a64fcf ("HID: bpf: allocate data memory for device_event BPF programs")
Signed-off-by: Yiyang Chen <chenyy23@mails.tsinghua.edu.cn>
---
drivers/hid/bpf/hid_bpf_dispatch.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/hid/bpf/hid_bpf_dispatch.c b/drivers/hid/bpf/hid_bpf_dispatch.c
index d0130658091b0..09b45c40d84f0 100644
--- a/drivers/hid/bpf/hid_bpf_dispatch.c
+++ b/drivers/hid/bpf/hid_bpf_dispatch.c
@@ -299,7 +299,8 @@ hid_bpf_get_data(struct hid_bpf_ctx *ctx, unsigned int offset, const size_t rdwr
ctx_kern = container_of(ctx, struct hid_bpf_ctx_kern, ctx);
- if (rdwr_buf_size + offset > ctx->allocated_size)
+ if (offset > ctx->allocated_size ||
+ rdwr_buf_size > ctx->allocated_size - offset)
return NULL;
return ctx_kern->data + offset;
--
2.34.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH bpf-next v2 2/2] selftests/hid: Cover hid_bpf_get_data() size overflow
2026-06-20 14:22 ` [PATCH bpf-next v2 0/2] HID: bpf: Fix hid_bpf_get_data() range check Yiyang Chen
2026-06-20 14:22 ` [PATCH bpf-next v2 1/2] " Yiyang Chen
@ 2026-06-20 14:22 ` Yiyang Chen
2026-06-20 15:11 ` bot+bpf-ci
1 sibling, 1 reply; 10+ messages in thread
From: Yiyang Chen @ 2026-06-20 14:22 UTC (permalink / raw)
To: Jiri Kosina, Benjamin Tissoires, bpf, linux-input
Cc: Yiyang Chen, Shuah Khan, Alexei Starovoitov, Daniel Borkmann,
Andrii Nakryiko, Martin KaFai Lau, Eduard Zingerman,
Kumar Kartikeya Dwivedi, Song Liu, Yonghong Song, Jiri Olsa,
linux-kselftest, linux-kernel
Add a HID-BPF regression check for hid_bpf_get_data() requests whose
size would overflow when added to the offset.
The new rdesc fixup callback asks for offset 2 and size ~0ULL, then
records whether the helper returns NULL. A vulnerable kernel returns a
non-NULL pointer because the runtime check wraps the addition. A fixed
kernel rejects the request. The test only checks the helper result and
does not dereference the returned pointer.
Also add KHDR_INCLUDES to the HID selftest build so hid_bpf.c sees the
current kernel UAPI HID definitions on systems whose installed headers do
not provide enum hid_report_type.
Signed-off-by: Yiyang Chen <chenyy23@mails.tsinghua.edu.cn>
---
tools/testing/selftests/hid/Makefile | 2 +-
tools/testing/selftests/hid/hid_bpf.c | 11 +++++++++++
tools/testing/selftests/hid/progs/hid.c | 15 +++++++++++++++
3 files changed, 27 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/hid/Makefile b/tools/testing/selftests/hid/Makefile
index 50ec9e0406aba..357c6eb5ff5ee 100644
--- a/tools/testing/selftests/hid/Makefile
+++ b/tools/testing/selftests/hid/Makefile
@@ -24,7 +24,7 @@ CXX ?= $(CROSS_COMPILE)g++
HOSTPKG_CONFIG := pkg-config
-CFLAGS += -g -O0 -rdynamic -Wall -Werror -I$(OUTPUT)
+CFLAGS += -g -O0 -rdynamic -Wall -Werror -I$(OUTPUT) $(KHDR_INCLUDES)
CFLAGS += -I$(OUTPUT)/tools/include
LDLIBS += -lelf -lz -lrt -lpthread
diff --git a/tools/testing/selftests/hid/hid_bpf.c b/tools/testing/selftests/hid/hid_bpf.c
index 1e979fb3542ba..f0a210900e63d 100644
--- a/tools/testing/selftests/hid/hid_bpf.c
+++ b/tools/testing/selftests/hid/hid_bpf.c
@@ -887,6 +887,17 @@ TEST_F(hid_bpf, test_rdesc_fixup)
ASSERT_EQ(rpt_desc.value[4], 0x42);
}
+TEST_F(hid_bpf, test_rdesc_fixup_get_data_overflow)
+{
+ const struct test_program progs[] = {
+ { .name = "hid_rdesc_fixup_get_data_overflow" },
+ };
+
+ LOAD_PROGRAMS(progs);
+
+ ASSERT_EQ(self->skel->bss->get_data_overflow_check, 1);
+}
+
static int libbpf_print_fn(enum libbpf_print_level level,
const char *format, va_list args)
{
diff --git a/tools/testing/selftests/hid/progs/hid.c b/tools/testing/selftests/hid/progs/hid.c
index 5ecc845ef7921..b21fbb13c926f 100644
--- a/tools/testing/selftests/hid/progs/hid.c
+++ b/tools/testing/selftests/hid/progs/hid.c
@@ -13,6 +13,7 @@ struct attach_prog_args {
__u64 callback_check = 52;
__u64 callback2_check = 52;
+__u64 get_data_overflow_check;
SEC("?struct_ops/hid_device_event")
int BPF_PROG(hid_first_event, struct hid_bpf_ctx *hid_ctx, enum hid_report_type type)
@@ -240,6 +241,20 @@ struct hid_bpf_ops rdesc_fixup = {
.hid_rdesc_fixup = (void *)hid_rdesc_fixup,
};
+SEC("?struct_ops.s/hid_rdesc_fixup")
+int BPF_PROG(hid_rdesc_fixup_get_data_overflow, struct hid_bpf_ctx *hid_ctx)
+{
+ if (!hid_bpf_get_data(hid_ctx, 2 /* offset */, ~0ULL /* size */))
+ get_data_overflow_check = 1;
+
+ return 0;
+}
+
+SEC(".struct_ops.link")
+struct hid_bpf_ops rdesc_fixup_get_data_overflow = {
+ .hid_rdesc_fixup = (void *)hid_rdesc_fixup_get_data_overflow,
+};
+
SEC("?struct_ops/hid_device_event")
int BPF_PROG(hid_test_insert1, struct hid_bpf_ctx *hid_ctx, enum hid_report_type type)
{
--
2.34.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH bpf-next v2 2/2] selftests/hid: Cover hid_bpf_get_data() size overflow
2026-06-20 14:22 ` [PATCH bpf-next v2 2/2] selftests/hid: Cover hid_bpf_get_data() size overflow Yiyang Chen
@ 2026-06-20 15:11 ` bot+bpf-ci
0 siblings, 0 replies; 10+ messages in thread
From: bot+bpf-ci @ 2026-06-20 15:11 UTC (permalink / raw)
To: chenyy23, jikos, bentiss, bpf, linux-input
Cc: chenyy23, shuah, ast, daniel, andrii, martin.lau, eddyz87, memxor,
song, yonghong.song, jolsa, linux-kselftest, linux-kernel, ast,
andrii, daniel, martin.lau, eddyz87, yonghong.song, clm,
ihor.solodrai
[-- Attachment #1: Type: text/plain, Size: 2441 bytes --]
> selftests/hid: Cover hid_bpf_get_data() size overflow
>
> Add a HID-BPF regression check for hid_bpf_get_data() requests whose
> size would overflow when added to the offset.
>
> The new rdesc fixup callback asks for offset 2 and size ~0ULL, then
> records whether the helper returns NULL. A vulnerable kernel returns a
> non-NULL pointer because the runtime check wraps the addition. A fixed
> kernel rejects the request. The test only checks the helper result and
> does not dereference the returned pointer.
>
> Also add KHDR_INCLUDES to the HID selftest build so hid_bpf.c sees the
> current kernel UAPI HID definitions on systems whose installed headers do
> not provide enum hid_report_type.
>
> Signed-off-by: Yiyang Chen <chenyy23@mails.tsinghua.edu.cn>
This adds a regression test for the hid_bpf_get_data() size-overflow
bug, where the range check wrapped on a large size and returned an
out-of-bounds pointer.
That wrapping check was introduced in 658ee5a64fcf, and the fix commit
carries a Fixes: tag for it. Should this test commit carry the same tag?
Fixes: 658ee5a64fcf ("HID: bpf: allocate data memory for device_event BPF programs")
> diff --git a/tools/testing/selftests/hid/progs/hid.c b/tools/testing/selftests/hid/progs/hid.c
> index 5ecc845ef792..b21fbb13c926 100644
> --- a/tools/testing/selftests/hid/progs/hid.c
> +++ b/tools/testing/selftests/hid/progs/hid.c
> @@ -240,6 +241,20 @@ struct hid_bpf_ops rdesc_fixup = {
> .hid_rdesc_fixup = (void *)hid_rdesc_fixup,
> };
>
> +SEC("?struct_ops.s/hid_rdesc_fixup")
> +int BPF_PROG(hid_rdesc_fixup_get_data_overflow, struct hid_bpf_ctx *hid_ctx)
> +{
> + if (!hid_bpf_get_data(hid_ctx, 2 /* offset */, ~0ULL /* size */))
> + get_data_overflow_check = 1;
> +
> + return 0;
> +}
This was raised on an earlier posting and does not look addressed:
the callback stores the result in the get_data_overflow_check global
and always returns 0, while the userspace test asserts on that global
rather than on the callback return value.
Could the callback just return the helper result so the test can check
the return value directly, instead of routing it through a separate
global?
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/27874238868
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2026-06-20 15:11 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-16 16:35 [PATCH bpf-next 0/2] HID: bpf: Fix hid_bpf_get_data() range check Yiyang Chen
2026-06-16 16:35 ` [PATCH bpf-next 1/2] " Yiyang Chen
2026-06-16 17:18 ` bot+bpf-ci
2026-06-16 22:52 ` Emil Tsalapatis
2026-06-16 16:35 ` [PATCH bpf-next 2/2] selftests/hid: Cover hid_bpf_get_data() size overflow Yiyang Chen
2026-06-16 23:03 ` Emil Tsalapatis
2026-06-20 14:22 ` [PATCH bpf-next v2 0/2] HID: bpf: Fix hid_bpf_get_data() range check Yiyang Chen
2026-06-20 14:22 ` [PATCH bpf-next v2 1/2] " Yiyang Chen
2026-06-20 14:22 ` [PATCH bpf-next v2 2/2] selftests/hid: Cover hid_bpf_get_data() size overflow Yiyang Chen
2026-06-20 15:11 ` bot+bpf-ci
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox