[PATCH bpf-next v3 10/17] selftests/bpf: add test for user call of HID bpf programs

From: Benjamin Tissoires
Date: Fri Mar 18 2022 - 12:18:33 EST


Add a simple test to see if we can trigger a bpf program of type
"hid/user_event".

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@xxxxxxxxxx>

---

changes in v3:
- use the new hid_get_data API

changes in v2:
- split the series by bpf/libbpf/hid/selftests and samples
---
tools/testing/selftests/bpf/prog_tests/hid.c | 56 ++++++++++++++++++++
tools/testing/selftests/bpf/progs/hid.c | 15 ++++++
2 files changed, 71 insertions(+)

diff --git a/tools/testing/selftests/bpf/prog_tests/hid.c b/tools/testing/selftests/bpf/prog_tests/hid.c
index b8d4dcf20b05..edc3af71e9ed 100644
--- a/tools/testing/selftests/bpf/prog_tests/hid.c
+++ b/tools/testing/selftests/bpf/prog_tests/hid.c
@@ -478,6 +478,59 @@ static int test_hid_attach_flags(struct hid *hid_skel, int uhid_fd, int sysfs_fd
return ret;
}

+/*
+ * Attach hid_user to the given uhid device,
+ * call the bpf program from userspace
+ * check that the program is called and does the expected.
+ */
+static int test_hid_user_call(struct hid *hid_skel, int uhid_fd, int sysfs_fd)
+{
+ int err, prog_fd;
+ u8 buf[10] = {0};
+ int ret = -1;
+
+ LIBBPF_OPTS(bpf_test_run_opts, run_attrs,
+ .repeat = 1,
+ .ctx_in = &sysfs_fd,
+ .ctx_size_in = sizeof(sysfs_fd),
+ .data_in = buf,
+ .data_size_in = sizeof(buf),
+ .data_out = buf,
+ .data_size_out = sizeof(buf),
+ );
+
+ /* attach hid_user program */
+ hid_skel->links.hid_user = bpf_program__attach_hid(hid_skel->progs.hid_user, sysfs_fd, 0);
+ if (!ASSERT_OK_PTR(hid_skel->links.hid_user,
+ "attach_hid(hid_user)"))
+ return PTR_ERR(hid_skel->links.hid_user);
+
+ buf[0] = 39;
+
+ prog_fd = bpf_program__fd(hid_skel->progs.hid_user);
+
+ err = bpf_prog_test_run_opts(prog_fd, &run_attrs);
+ if (!ASSERT_EQ(err, 0, "bpf_prog_test_run_xattr"))
+ goto cleanup;
+
+ if (!ASSERT_EQ(run_attrs.retval, 72, "bpf_prog_test_run_opts"))
+ goto cleanup;
+
+ if (!ASSERT_EQ(buf[1], 42, "hid_user_check_in"))
+ goto cleanup;
+
+ if (!ASSERT_EQ(buf[2], 4, "hid_user_check_static_out"))
+ goto cleanup;
+
+ ret = 0;
+
+cleanup:
+
+ hid__detach(hid_skel);
+
+ return ret;
+}
+
/*
* Attach hid_rdesc_fixup to the given uhid device,
* retrieve and open the matching hidraw node,
@@ -585,6 +638,9 @@ void serial_test_hid_bpf(void)
err = test_hid_attach_flags(hid_skel, uhid_fd, sysfs_fd);
ASSERT_OK(err, "hid_user_raw_request");

+ err = test_hid_user_call(hid_skel, uhid_fd, sysfs_fd);
+ ASSERT_OK(err, "hid_user");
+
/*
* this test should be run last because we disconnect/reconnect
* the device, meaning that it changes the overall uhid device
diff --git a/tools/testing/selftests/bpf/progs/hid.c b/tools/testing/selftests/bpf/progs/hid.c
index 390c1bb8d850..fbdbe9d1b605 100644
--- a/tools/testing/selftests/bpf/progs/hid.c
+++ b/tools/testing/selftests/bpf/progs/hid.c
@@ -128,3 +128,18 @@ int hid_test_insert3(struct hid_bpf_ctx *ctx)

return 0;
}
+
+SEC("hid/user_event")
+int hid_user(struct hid_bpf_ctx *ctx)
+{
+ __u8 *data = bpf_hid_get_data(ctx, 0 /* offset */, 3 /* size */);
+
+ if (!data)
+ return 0; /* EPERM check */
+
+ data[1] = data[0] + 3;
+ data[2] = 4;
+ ctx->retval = 72;
+
+ return 0;
+}
--
2.35.1