Commit 80e189f2 authored by Benjamin Tissoires's avatar Benjamin Tissoires Committed by Jiri Kosina
Browse files

selftests/hid: Add a test for BPF_F_INSERT_HEAD



Insert 3 programs to check that we are doing the correct thing:
'2', '1', '3' are inserted, but '1' is supposed to be executed first.

Signed-off-by: default avatarBenjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
parent e8445737
Loading
Loading
Loading
Loading
+43 −0
Original line number Diff line number Diff line
@@ -88,6 +88,7 @@ struct attach_prog_args {
	int prog_fd;
	unsigned int hid;
	int retval;
	int insert_head;
};

struct hid_hw_request_syscall_args {
@@ -490,6 +491,7 @@ FIXTURE_SETUP(hid_bpf)

struct test_program {
	const char *name;
	int insert_head;
};
#define LOAD_PROGRAMS(progs) \
	load_programs(progs, ARRAY_SIZE(progs), _metadata, self, variant)
@@ -539,6 +541,7 @@ static void load_programs(const struct test_program programs[],

		args.prog_fd = bpf_program__fd(prog);
		args.hid = self->hid_id;
		args.insert_head = programs[i].insert_head;
		err = bpf_prog_test_run_opts(attach_fd, &tattr);
		ASSERT_OK(args.retval) TH_LOG("attach_hid(%s): %d", programs[i].name, args.retval);
	}
@@ -740,6 +743,46 @@ TEST_F(hid_bpf, test_hid_user_raw_request_call)
	ASSERT_EQ(args.data[1], 2);
}

/*
 * Attach hid_insert{0,1,2} to the given uhid device,
 * retrieve and open the matching hidraw node,
 * inject one event in the uhid device,
 * check that the programs have been inserted in the correct order.
 */
TEST_F(hid_bpf, test_hid_attach_flags)
{
	const struct test_program progs[] = {
		{
			.name = "hid_test_insert2",
			.insert_head = 0,
		},
		{
			.name = "hid_test_insert1",
			.insert_head = 1,
		},
		{
			.name = "hid_test_insert3",
			.insert_head = 0,
		},
	};
	__u8 buf[10] = {0};
	int err;

	LOAD_PROGRAMS(progs);

	/* inject one event */
	buf[0] = 1;
	uhid_send_event(_metadata, self->uhid_fd, buf, 6);

	/* 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[1], 1);
	ASSERT_EQ(buf[2], 2);
	ASSERT_EQ(buf[3], 3);
}

/*
 * Attach hid_rdesc_fixup to the given uhid device,
 * retrieve and open the matching hidraw node,
+54 −1
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@ struct attach_prog_args {
	int prog_fd;
	unsigned int hid;
	int retval;
	int insert_head;
};

__u64 callback_check = 52;
@@ -49,7 +50,8 @@ int attach_prog(struct attach_prog_args *ctx)
{
	ctx->retval = hid_bpf_attach_prog(ctx->hid,
					  ctx->prog_fd,
					  0);
					  ctx->insert_head ? HID_BPF_FLAG_INSERT_HEAD :
							     HID_BPF_FLAG_NONE);
	return 0;
}

@@ -141,3 +143,54 @@ int BPF_PROG(hid_rdesc_fixup, struct hid_bpf_ctx *hid_ctx)

	return sizeof(rdesc) + 73;
}

SEC("?fmod_ret/hid_bpf_device_event")
int BPF_PROG(hid_test_insert1, struct hid_bpf_ctx *hid_ctx)
{
	__u8 *data = hid_bpf_get_data(hid_ctx, 0 /* offset */, 4 /* size */);

	if (!data)
		return 0; /* EPERM check */

	/* we need to be run first */
	if (data[2] || data[3])
		return -1;

	data[1] = 1;

	return 0;
}

SEC("?fmod_ret/hid_bpf_device_event")
int BPF_PROG(hid_test_insert2, struct hid_bpf_ctx *hid_ctx)
{
	__u8 *data = hid_bpf_get_data(hid_ctx, 0 /* offset */, 4 /* size */);

	if (!data)
		return 0; /* EPERM check */

	/* after insert0 and before insert2 */
	if (!data[1] || data[3])
		return -1;

	data[2] = 2;

	return 0;
}

SEC("?fmod_ret/hid_bpf_device_event")
int BPF_PROG(hid_test_insert3, struct hid_bpf_ctx *hid_ctx)
{
	__u8 *data = hid_bpf_get_data(hid_ctx, 0 /* offset */, 4 /* size */);

	if (!data)
		return 0; /* EPERM check */

	/* at the end */
	if (!data[1] || !data[2])
		return -1;

	data[3] = 3;

	return 0;
}