mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git/
synced 2026-04-17 22:23:45 -04:00
selftests/hid: add report descriptor fixup tests
Simple report descriptor override in HID: replace part of the report descriptor from a static definition in the bpf kernel program. Note that this test should be run last because we disconnect/reconnect the device, meaning that it changes the overall uhid device. Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
This commit is contained in:
committed by
Jiri Kosina
parent
ad190df11a
commit
e8445737c0
@@ -740,6 +740,38 @@ TEST_F(hid_bpf, test_hid_user_raw_request_call)
|
||||
ASSERT_EQ(args.data[1], 2);
|
||||
}
|
||||
|
||||
/*
|
||||
* Attach hid_rdesc_fixup to the given uhid device,
|
||||
* retrieve and open the matching hidraw node,
|
||||
* check that the hidraw report descriptor has been updated.
|
||||
*/
|
||||
TEST_F(hid_bpf, test_rdesc_fixup)
|
||||
{
|
||||
struct hidraw_report_descriptor rpt_desc = {0};
|
||||
const struct test_program progs[] = {
|
||||
{ .name = "hid_rdesc_fixup" },
|
||||
};
|
||||
int err, desc_size;
|
||||
|
||||
LOAD_PROGRAMS(progs);
|
||||
|
||||
/* check that hid_rdesc_fixup() was executed */
|
||||
ASSERT_EQ(self->skel->data->callback2_check, 0x21);
|
||||
|
||||
/* read the exposed report descriptor from hidraw */
|
||||
err = ioctl(self->hidraw_fd, HIDIOCGRDESCSIZE, &desc_size);
|
||||
ASSERT_GE(err, 0) TH_LOG("error while reading HIDIOCGRDESCSIZE: %d", err);
|
||||
|
||||
/* ensure the new size of the rdesc is bigger than the old one */
|
||||
ASSERT_GT(desc_size, sizeof(rdesc));
|
||||
|
||||
rpt_desc.size = desc_size;
|
||||
err = ioctl(self->hidraw_fd, HIDIOCGRDESC, &rpt_desc);
|
||||
ASSERT_GE(err, 0) TH_LOG("error while reading HIDIOCGRDESC: %d", err);
|
||||
|
||||
ASSERT_EQ(rpt_desc.value[4], 0x42);
|
||||
}
|
||||
|
||||
static int libbpf_print_fn(enum libbpf_print_level level,
|
||||
const char *format, va_list args)
|
||||
{
|
||||
|
||||
@@ -88,3 +88,56 @@ int hid_user_raw_request(struct hid_hw_request_syscall_args *args)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const __u8 rdesc[] = {
|
||||
0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */
|
||||
0x09, 0x32, /* USAGE (Z) */
|
||||
0x95, 0x01, /* REPORT_COUNT (1) */
|
||||
0x81, 0x06, /* INPUT (Data,Var,Rel) */
|
||||
|
||||
0x06, 0x00, 0xff, /* Usage Page (Vendor Defined Page 1) */
|
||||
0x19, 0x01, /* USAGE_MINIMUM (1) */
|
||||
0x29, 0x03, /* USAGE_MAXIMUM (3) */
|
||||
0x15, 0x00, /* LOGICAL_MINIMUM (0) */
|
||||
0x25, 0x01, /* LOGICAL_MAXIMUM (1) */
|
||||
0x95, 0x03, /* REPORT_COUNT (3) */
|
||||
0x75, 0x01, /* REPORT_SIZE (1) */
|
||||
0x91, 0x02, /* Output (Data,Var,Abs) */
|
||||
0x95, 0x01, /* REPORT_COUNT (1) */
|
||||
0x75, 0x05, /* REPORT_SIZE (5) */
|
||||
0x91, 0x01, /* Output (Cnst,Var,Abs) */
|
||||
|
||||
0x06, 0x00, 0xff, /* Usage Page (Vendor Defined Page 1) */
|
||||
0x19, 0x06, /* USAGE_MINIMUM (6) */
|
||||
0x29, 0x08, /* USAGE_MAXIMUM (8) */
|
||||
0x15, 0x00, /* LOGICAL_MINIMUM (0) */
|
||||
0x25, 0x01, /* LOGICAL_MAXIMUM (1) */
|
||||
0x95, 0x03, /* REPORT_COUNT (3) */
|
||||
0x75, 0x01, /* REPORT_SIZE (1) */
|
||||
0xb1, 0x02, /* Feature (Data,Var,Abs) */
|
||||
0x95, 0x01, /* REPORT_COUNT (1) */
|
||||
0x75, 0x05, /* REPORT_SIZE (5) */
|
||||
0x91, 0x01, /* Output (Cnst,Var,Abs) */
|
||||
|
||||
0xc0, /* END_COLLECTION */
|
||||
0xc0, /* END_COLLECTION */
|
||||
};
|
||||
|
||||
SEC("?fmod_ret/hid_bpf_rdesc_fixup")
|
||||
int BPF_PROG(hid_rdesc_fixup, struct hid_bpf_ctx *hid_ctx)
|
||||
{
|
||||
__u8 *data = hid_bpf_get_data(hid_ctx, 0 /* offset */, 4096 /* size */);
|
||||
|
||||
if (!data)
|
||||
return 0; /* EPERM check */
|
||||
|
||||
callback2_check = data[4];
|
||||
|
||||
/* insert rdesc at offset 73 */
|
||||
__builtin_memcpy(&data[73], rdesc, sizeof(rdesc));
|
||||
|
||||
/* Change Usage Vendor globally */
|
||||
data[4] = 0x42;
|
||||
|
||||
return sizeof(rdesc) + 73;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user