* [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; 6+ 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] 6+ 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 1 sibling, 2 replies; 6+ 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] 6+ 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; 6+ 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] 6+ 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; 6+ 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] 6+ 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 1 sibling, 1 reply; 6+ 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] 6+ 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; 6+ 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] 6+ messages in thread
end of thread, other threads:[~2026-06-16 23:03 UTC | newest] Thread overview: 6+ 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
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox