From: Yiyang Chen Date: Tue, 23 Jun 2026 06:23:15 +0000 (+0000) Subject: selftests/hid: Cover hid_bpf_get_data() size overflow X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=eebbef7c468a5cb58c4772849ee5066441166cf0;p=thirdparty%2Fkernel%2Flinux.git 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 callback records the helper result without dereferencing any 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 Signed-off-by: Benjamin Tissoires --- diff --git a/tools/testing/selftests/hid/Makefile b/tools/testing/selftests/hid/Makefile index 96071b4800e82..2f423de831473 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) {