selftests/hid: add unnumbered variant to the hid_bpf tests

A bug appeared in hid_bpf_dispatch.c where it wasn't properly handling
unnumbered reports. Add a device variant without report IDs so we can
also test them.

Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
This commit is contained in:
Benjamin Tissoires 2026-09-04 14:53:01 +02:00
parent c4afa4862b
commit b6f69097c8
3 changed files with 68 additions and 11 deletions

View File

@ -54,11 +54,27 @@ FIXTURE_TEARDOWN(hid_bpf) {
hid_bpf_teardown(_metadata, self, variant); \
} while (0)
FIXTURE_VARIANT(hid_bpf) {
__u8 *rdesc;
size_t rdesc_size;
};
FIXTURE_VARIANT_ADD(hid_bpf, numbered) {
.rdesc = rdesc,
.rdesc_size = sizeof(rdesc),
};
FIXTURE_VARIANT_ADD(hid_bpf, unnumbered) {
.rdesc = fido2_rdesc,
.rdesc_size = sizeof(fido2_rdesc),
};
FIXTURE_SETUP(hid_bpf)
{
int err;
err = setup_uhid(_metadata, &self->hid, BUS_USB, 0x0001, 0x0a36, rdesc, sizeof(rdesc));
err = setup_uhid(_metadata, &self->hid, BUS_USB, 0x0001, 0x0a36,
variant->rdesc, variant->rdesc_size);
ASSERT_OK(err);
}
@ -409,8 +425,11 @@ TEST_F(hid_bpf, test_hid_user_input_report_call)
args.hid = self->hid.hid_id;
args.data[0] = 1; /* report ID */
args.data[1] = 2; /* report ID */
args.data[2] = 42; /* report ID */
args.data[1] = 2;
args.data[2] = 42;
if (variant->rdesc == fido2_rdesc)
args.data[0] = 0;
prog_fd = bpf_program__fd(self->skel->progs.hid_user_input_report);
@ -428,8 +447,13 @@ TEST_F(hid_bpf, test_hid_user_input_report_call)
/* read the data from hidraw */
memset(buf, 0, sizeof(buf));
err = read(self->hidraw_fd, buf, sizeof(buf));
ASSERT_EQ(err, 6) TH_LOG("read_hidraw");
ASSERT_EQ(buf[0], 1);
if (variant->rdesc == rdesc) {
ASSERT_EQ(err, 6) TH_LOG("read_hidraw");
} else {
ASSERT_EQ(err, 64)
TH_LOG("read_hidraw");
}
ASSERT_EQ(buf[0], args.data[0]);
ASSERT_EQ(buf[1], 2);
ASSERT_EQ(buf[2], 42);
}
@ -455,8 +479,11 @@ TEST_F(hid_bpf, test_hid_user_output_report_call)
args.hid = self->hid.hid_id;
args.data[0] = 1; /* report ID */
args.data[1] = 2; /* report ID */
args.data[2] = 42; /* report ID */
args.data[1] = 2;
args.data[2] = 42;
if (variant->rdesc == fido2_rdesc)
args.data[0] = 0;
prog_fd = bpf_program__fd(self->skel->progs.hid_user_output_report);
@ -472,9 +499,14 @@ TEST_F(hid_bpf, test_hid_user_output_report_call)
ASSERT_OK(err) TH_LOG("error while calling bpf_prog_test_run_opts");
ASSERT_OK(cond_err) TH_LOG("error while calling waiting for the condition");
ASSERT_EQ(args.retval, 3);
if (variant->rdesc == rdesc) {
ASSERT_EQ(args.retval, 3);
} else if (variant->rdesc == fido2_rdesc) {
ASSERT_EQ(args.retval, 65)
TH_LOG("report size error, should have 64 + 1 extra byte for the report ID 0");
}
ASSERT_EQ(output_report[0], 1);
ASSERT_EQ(output_report[0], args.data[0]);
ASSERT_EQ(output_report[1], 2);
ASSERT_EQ(output_report[2], 42);
@ -886,6 +918,9 @@ TEST_F(hid_bpf, test_rdesc_fixup)
};
int err, desc_size;
if (variant->rdesc != rdesc)
SKIP(return, "not compatible report descriptor");
LOAD_PROGRAMS(progs);
/* check that hid_rdesc_fixup() was executed */

View File

@ -13,7 +13,7 @@
#include <linux/uhid.h>
#define SHOW_UHID_DEBUG 0
#define MAX_BUF_SIZE 10
#define MAX_BUF_SIZE 128
#define min(a, b) \
({ __typeof__(a) _a = (a); \
@ -98,6 +98,28 @@ static unsigned char rdesc[] = {
static __u8 feature_data[] = { 1, 2 };
static __maybe_unused unsigned char fido2_rdesc[] = {
0x06, 0xd0, 0xf1, /* Usage Page (FIDO Alliance) */
0x09, 0x01, /* Usage (U2F Authenticator Device) */
0xa1, 0x01, /* Collection (Application) */
0x09, 0x20, /* Usage (Input Report Data) */
0x15, 0x00, /* Logical Minimum (0) */
0x26, 0xff, 0x00, /* Logical Maximum (255) */
0x75, 0x08, /* Report Size (8) */
0x95, 0x40, /* Report Count (64) */
0x81, 0x02, /* Input (Data,Var,Abs) */
0x09, 0x21, /* Usage (Output Report Data) */
0x15, 0x00, /* Logical Minimum (0) */
0x26, 0xff, 0x00, /* Logical Maximum (255) */
0x75, 0x08, /* Report Size (8) */
0x95, 0x40, /* Report Count (64) */
0x91, 0x02, /* Output (Data,Var,Abs) */
0x06, 0x00, 0xff, /* Usage Page (Vendor Defined Page 1) */
0x09, 0x22, /* Usage (Vendor Usage 0x22) */
0xb1, 0x02, /* Feature (Data,Var,Abs) */
0xc0, /* End Collection */
};
#define ASSERT_OK(data) ASSERT_FALSE(data)
#define ASSERT_OK_PTR(ptr) ASSERT_NE(NULL, ptr)

View File

@ -98,7 +98,7 @@ struct hid_bpf_ops change_report_id = {
struct hid_hw_request_syscall_args {
/* data needs to come at offset 0 so we can use it in calls */
__u8 data[10];
__u8 data[128];
unsigned int hid;
int retval;
size_t size;