* [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; 16+ 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] 16+ 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; 16+ 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] 16+ 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; 16+ 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] 16+ 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; 16+ 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] 16+ 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; 16+ 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] 16+ 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; 16+ 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] 16+ 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
` (2 more replies)
2 siblings, 3 replies; 16+ 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] 16+ 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
2026-06-22 6:52 ` [PATCH bpf-next v3 0/3] HID: bpf: Fix hid_bpf_get_data() range check Yiyang Chen
2 siblings, 0 replies; 16+ 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] 16+ 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
2026-06-22 6:52 ` [PATCH bpf-next v3 0/3] HID: bpf: Fix hid_bpf_get_data() range check Yiyang Chen
2 siblings, 1 reply; 16+ 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] 16+ 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
2026-06-22 5:50 ` Yiyang Chen
0 siblings, 1 reply; 16+ 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] 16+ messages in thread
* Re: [PATCH bpf-next v2 2/2] selftests/hid: Cover hid_bpf_get_data() size overflow
2026-06-20 15:11 ` bot+bpf-ci
@ 2026-06-22 5:50 ` Yiyang Chen
0 siblings, 0 replies; 16+ messages in thread
From: Yiyang Chen @ 2026-06-22 5:50 UTC (permalink / raw)
To: bot+bpf-ci
Cc: andrii, ast, bentiss, bpf, chenyy23, clm, daniel, eddyz87,
ihor.solodrai, jikos, jolsa, linux-input, linux-kernel,
linux-kselftest, martin.lau, martin.lau, memxor, shuah, song,
yonghong.song
On Sat, Jun 20, 2026 at 03:11:00PM +0000, bot+bpf-ci@kernel.org wrote:
> 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")
Yes, I will add the same Fixes tag to the selftest patch in v3 so the
regression test is tied to the commit that introduced the wrapping check.
> 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?
The callback's return value is not something the test can observe
directly. call_hid_bpf_rdesc_fixup() consumes it as a kernel-side
contract: a negative value falls back to the original report descriptor,
and a positive value becomes the new descriptor size (*size = ret). Its
only userspace-visible effect is therefore the report descriptor size,
so checking the return value would amount to checking that size, which
means perturbing it.
Since the callback returns int and hid_bpf_get_data() returns a pointer,
the only way to return the helper result is to convert it, e.g.
return !hid_bpf_get_data(hid_ctx, 2, ~0ULL);
On a fixed kernel the helper returns NULL, so this returns 1 and the
dispatch path truncates the report descriptor to 1 byte mid-test. The
BSS variable records that the helper rejected the overflowing range
while the callback still returns 0 and leaves the descriptor untouched.
This matches the existing convention in progs/hid.c: callback_check and
callback2_check are BPF-side globals the userspace tests assert on, and
the existing hid_rdesc_fixup callback returns a positive size only when
it actually rewrites the descriptor (sizeof(rdesc) + 73). The overflow
probe does not rewrite anything, so it returns 0 and reports the
helper's rejection through the BSS variable.
Thanks,
Yiyang
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH bpf-next v3 0/3] 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 ` [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-22 6:52 ` Yiyang Chen
2026-06-22 7:30 ` [PATCH bpf-next v3 1/3] " Yiyang Chen
2 siblings, 1 reply; 16+ messages in thread
From: Yiyang Chen @ 2026-06-22 6:52 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 updates the HID selftest loader to create only the struct_ops
maps requested by the current test, so unrelated programs from the shared
HID-BPF skeleton are not autoloaded.
Patch 3 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.
Changes in v3:
- Split out a HID selftest loader fix that disables autocreate for
unrelated struct_ops maps.
- Add a Fixes tag to the selftest patch.
- Keep the BSS result flag in the rdesc fixup callback and explain why
the callback must still return 0.
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").
v2: https://lore.kernel.org/bpf/cover.1781964949.git.chenyy23@mails.tsinghua.edu.cn/
v1: https://lore.kernel.org/bpf/cover.1781627122.git.chenyy23@mails.tsinghua.edu.cn/
Yiyang Chen (3):
HID: bpf: Fix hid_bpf_get_data() range check
selftests/hid: Load only requested struct_ops maps
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 | 36 ++++++++++++++++++++-----
tools/testing/selftests/hid/progs/hid.c | 15 +++++++++++
4 files changed, 47 insertions(+), 9 deletions(-)
base-commit: a975094bf98ca97be9146f9d3b5681a6f9cf5ce3
--
2.34.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH bpf-next v3 1/3] HID: bpf: Fix hid_bpf_get_data() range check
2026-06-22 6:52 ` [PATCH bpf-next v3 0/3] HID: bpf: Fix hid_bpf_get_data() range check Yiyang Chen
@ 2026-06-22 7:30 ` Yiyang Chen
2026-06-22 7:30 ` [PATCH bpf-next v3 2/3] selftests/hid: Load only requested struct_ops maps Yiyang Chen
` (2 more replies)
0 siblings, 3 replies; 16+ messages in thread
From: Yiyang Chen @ 2026-06-22 7:30 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] 16+ messages in thread
* [PATCH bpf-next v3 2/3] selftests/hid: Load only requested struct_ops maps
2026-06-22 7:30 ` [PATCH bpf-next v3 1/3] " Yiyang Chen
@ 2026-06-22 7:30 ` Yiyang Chen
2026-06-22 7:30 ` [PATCH bpf-next v3 3/3] selftests/hid: Cover hid_bpf_get_data() size overflow Yiyang Chen
2026-06-22 18:18 ` [PATCH bpf-next v3 1/3] HID: bpf: Fix hid_bpf_get_data() range check Eduard Zingerman
2 siblings, 0 replies; 16+ messages in thread
From: Yiyang Chen @ 2026-06-22 7:30 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
The HID selftest skeleton contains several struct_ops maps, but each test
usually wants to load only the programs named by that test.
load_programs() disabled auto-attach for all maps, but left struct_ops
autocreate enabled. libbpf can enable autoload for programs referenced by
autocreated struct_ops maps, so an unrelated program can be loaded and fail
even when the current test does not use it.
Disable autocreate for all struct_ops maps by default, then re-enable it
only for the maps selected by the test before loading the skeleton.
Signed-off-by: Yiyang Chen <chenyy23@mails.tsinghua.edu.cn>
---
tools/testing/selftests/hid/hid_bpf.c | 25 ++++++++++++++++++-------
1 file changed, 18 insertions(+), 7 deletions(-)
diff --git a/tools/testing/selftests/hid/hid_bpf.c b/tools/testing/selftests/hid/hid_bpf.c
index 1e979fb3542ba..269256e1decd8 100644
--- a/tools/testing/selftests/hid/hid_bpf.c
+++ b/tools/testing/selftests/hid/hid_bpf.c
@@ -86,6 +86,20 @@ static void load_programs(const struct test_program programs[],
self->skel = hid__open();
ASSERT_OK_PTR(self->skel) TEARDOWN_LOG("Error while calling hid__open");
+ /*
+ * Disable all struct_ops maps by default so libbpf does not autoload
+ * programs referenced by maps that are unrelated to the current test.
+ */
+ bpf_object__for_each_map(iter_map, *self->skel->skeleton->obj) {
+ if (bpf_map__type(iter_map) == BPF_MAP_TYPE_STRUCT_OPS) {
+ err = bpf_map__set_autocreate(iter_map, false);
+ ASSERT_OK(err) TH_LOG("can not disable struct_ops map '%s'",
+ bpf_map__name(iter_map));
+ }
+
+ bpf_map__set_autoattach(iter_map, false);
+ }
+
for (int i = 0; i < progs_count; i++) {
struct bpf_program *prog;
struct bpf_map *map;
@@ -102,6 +116,10 @@ static void load_programs(const struct test_program programs[],
ASSERT_OK_PTR(map) TH_LOG("can not find struct_ops by name '%s'",
programs[i].name + 4);
+ err = bpf_map__set_autocreate(map, true);
+ ASSERT_OK(err) TH_LOG("can not enable struct_ops map '%s'",
+ programs[i].name + 4);
+
/* hid_id is the first field of struct hid_bpf_ops */
ops_hid_id = bpf_map__initial_value(map, NULL);
ASSERT_OK_PTR(ops_hid_id) TH_LOG("unable to retrieve struct_ops data");
@@ -109,13 +127,6 @@ static void load_programs(const struct test_program programs[],
*ops_hid_id = self->hid.hid_id;
}
- /* we disable the auto-attach feature of all maps because we
- * only want the tested one to be manually attached in the next
- * call to bpf_map__attach_struct_ops()
- */
- bpf_object__for_each_map(iter_map, *self->skel->skeleton->obj)
- bpf_map__set_autoattach(iter_map, false);
-
err = hid__load(self->skel);
ASSERT_OK(err) TH_LOG("hid_skel_load failed: %d", err);
--
2.34.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH bpf-next v3 3/3] selftests/hid: Cover hid_bpf_get_data() size overflow
2026-06-22 7:30 ` [PATCH bpf-next v3 1/3] " Yiyang Chen
2026-06-22 7:30 ` [PATCH bpf-next v3 2/3] selftests/hid: Load only requested struct_ops maps Yiyang Chen
@ 2026-06-22 7:30 ` Yiyang Chen
2026-06-22 18:18 ` [PATCH bpf-next v3 1/3] HID: bpf: Fix hid_bpf_get_data() range check Eduard Zingerman
2 siblings, 0 replies; 16+ messages in thread
From: Yiyang Chen @ 2026-06-22 7:30 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.
The callback reports the helper result through BSS and returns 0
intentionally. hid_rdesc_fixup return values are consumed as report
descriptor fixup results, so a positive test-result value would be
interpreted as a replacement report descriptor size.
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.
Fixes: 658ee5a64fcf ("HID: bpf: allocate data memory for device_event BPF programs")
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 269256e1decd8..b851339308c21 100644
--- a/tools/testing/selftests/hid/hid_bpf.c
+++ b/tools/testing/selftests/hid/hid_bpf.c
@@ -898,6 +898,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] 16+ messages in thread
* Re: [PATCH bpf-next v3 1/3] HID: bpf: Fix hid_bpf_get_data() range check
2026-06-22 7:30 ` [PATCH bpf-next v3 1/3] " Yiyang Chen
2026-06-22 7:30 ` [PATCH bpf-next v3 2/3] selftests/hid: Load only requested struct_ops maps Yiyang Chen
2026-06-22 7:30 ` [PATCH bpf-next v3 3/3] selftests/hid: Cover hid_bpf_get_data() size overflow Yiyang Chen
@ 2026-06-22 18:18 ` Eduard Zingerman
2 siblings, 0 replies; 16+ messages in thread
From: Eduard Zingerman @ 2026-06-22 18:18 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, Kumar Kartikeya Dwivedi, Song Liu,
Yonghong Song, Jiri Olsa, linux-kselftest, linux-kernel
On Mon, 2026-06-22 at 07:30 +0000, 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.
>
> 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)
Nit: imo, this is harder to read, I'd define a variable to hold the
buffer end position, update it using check_add_overflow and
then compare it against ctx->allocated_size, e.g.:
if (check_add_overflow(rdwr_buf_size, offset, &end) || end > ctx->allocated_size)
...
pw-bot: cr
> return NULL;
>
> return ctx_kern->data + offset;
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2026-06-22 18:18 UTC | newest]
Thread overview: 16+ 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
2026-06-22 5:50 ` Yiyang Chen
2026-06-22 6:52 ` [PATCH bpf-next v3 0/3] HID: bpf: Fix hid_bpf_get_data() range check Yiyang Chen
2026-06-22 7:30 ` [PATCH bpf-next v3 1/3] " Yiyang Chen
2026-06-22 7:30 ` [PATCH bpf-next v3 2/3] selftests/hid: Load only requested struct_ops maps Yiyang Chen
2026-06-22 7:30 ` [PATCH bpf-next v3 3/3] selftests/hid: Cover hid_bpf_get_data() size overflow Yiyang Chen
2026-06-22 18:18 ` [PATCH bpf-next v3 1/3] HID: bpf: Fix hid_bpf_get_data() range check Eduard Zingerman
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox