Commit e8445737 authored by Benjamin Tissoires's avatar Benjamin Tissoires Committed by Jiri Kosina

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: default avatarBenjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
parent ad190df1
......@@ -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;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment