Linux Input/HID development
 help / color / mirror / Atom feed
* [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
  2026-06-16 16:35 ` [PATCH bpf-next 2/2] selftests/hid: Cover hid_bpf_get_data() size overflow Yiyang Chen
  0 siblings, 2 replies; 4+ 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] 4+ 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 16:35 ` [PATCH bpf-next 2/2] selftests/hid: Cover hid_bpf_get_data() size overflow Yiyang Chen
  1 sibling, 1 reply; 4+ 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] 4+ 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
  1 sibling, 0 replies; 4+ 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] 4+ 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
  0 siblings, 0 replies; 4+ 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] 4+ messages in thread

end of thread, other threads:[~2026-06-16 17:18 UTC | newest]

Thread overview: 4+ 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 16:35 ` [PATCH bpf-next 2/2] selftests/hid: Cover hid_bpf_get_data() size overflow Yiyang Chen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox