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: 658ee5a64f ("HID: bpf: allocate data memory for device_event BPF programs")
Signed-off-by: Yiyang Chen <chenyy23@mails.tsinghua.edu.cn>
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
This commit is contained in:
Yiyang Chen
2026-06-23 06:23:15 +00:00
committed by Benjamin Tissoires
parent 5aad55011a
commit eebbef7c46
3 changed files with 27 additions and 1 deletions

View File

@@ -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

View File

@@ -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)
{

View File

@@ -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)
{