mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-22 03:27:30 -04:00
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:
committed by
Benjamin Tissoires
parent
5aad55011a
commit
eebbef7c46
@@ -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
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user