mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-25 05:04:09 +08:00
selftests/hid: add tests for bpf_hid_hw_request
Add tests for the newly implemented function. We test here only the GET_REPORT part because the other calls are pure HID protocol and won't infer the result of the test of the bpf hook. Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
This commit is contained in:
parent
91a7f802d1
commit
4f7153cf46
@ -82,12 +82,23 @@ static unsigned char rdesc[] = {
|
||||
0xc0, /* END_COLLECTION */
|
||||
};
|
||||
|
||||
static __u8 feature_data[] = { 1, 2 };
|
||||
|
||||
struct attach_prog_args {
|
||||
int prog_fd;
|
||||
unsigned int hid;
|
||||
int retval;
|
||||
};
|
||||
|
||||
struct hid_hw_request_syscall_args {
|
||||
__u8 data[10];
|
||||
unsigned int hid;
|
||||
int retval;
|
||||
size_t size;
|
||||
enum hid_report_type type;
|
||||
__u8 request_type;
|
||||
};
|
||||
|
||||
#define ASSERT_OK(data) ASSERT_FALSE(data)
|
||||
#define ASSERT_OK_PTR(ptr) ASSERT_NE(NULL, ptr)
|
||||
|
||||
@ -155,7 +166,7 @@ static void uhid_destroy(struct __test_metadata *_metadata, int fd)
|
||||
|
||||
static int uhid_event(struct __test_metadata *_metadata, int fd)
|
||||
{
|
||||
struct uhid_event ev;
|
||||
struct uhid_event ev, answer;
|
||||
ssize_t ret;
|
||||
|
||||
memset(&ev, 0, sizeof(ev));
|
||||
@ -196,6 +207,15 @@ static int uhid_event(struct __test_metadata *_metadata, int fd)
|
||||
break;
|
||||
case UHID_GET_REPORT:
|
||||
UHID_LOG("UHID_GET_REPORT from uhid-dev");
|
||||
|
||||
answer.type = UHID_GET_REPORT_REPLY;
|
||||
answer.u.get_report_reply.id = ev.u.get_report.id;
|
||||
answer.u.get_report_reply.err = ev.u.get_report.rnum == 1 ? 0 : -EIO;
|
||||
answer.u.get_report_reply.size = sizeof(feature_data);
|
||||
memcpy(answer.u.get_report_reply.data, feature_data, sizeof(feature_data));
|
||||
|
||||
uhid_write(_metadata, fd, &answer);
|
||||
|
||||
break;
|
||||
case UHID_SET_REPORT:
|
||||
UHID_LOG("UHID_SET_REPORT from uhid-dev");
|
||||
@ -686,6 +706,40 @@ TEST_F(hid_bpf, test_hid_change_report)
|
||||
ASSERT_EQ(buf[2], 0) TH_LOG("leftovers_from_previous_test");
|
||||
}
|
||||
|
||||
/*
|
||||
* Attach hid_user_raw_request to the given uhid device,
|
||||
* call the bpf program from userspace
|
||||
* check that the program is called and does the expected.
|
||||
*/
|
||||
TEST_F(hid_bpf, test_hid_user_raw_request_call)
|
||||
{
|
||||
struct hid_hw_request_syscall_args args = {
|
||||
.retval = -1,
|
||||
.type = HID_FEATURE_REPORT,
|
||||
.request_type = HID_REQ_GET_REPORT,
|
||||
.size = 10,
|
||||
};
|
||||
DECLARE_LIBBPF_OPTS(bpf_test_run_opts, tattrs,
|
||||
.ctx_in = &args,
|
||||
.ctx_size_in = sizeof(args),
|
||||
);
|
||||
int err, prog_fd;
|
||||
|
||||
LOAD_BPF;
|
||||
|
||||
args.hid = self->hid_id;
|
||||
args.data[0] = 1; /* report ID */
|
||||
|
||||
prog_fd = bpf_program__fd(self->skel->progs.hid_user_raw_request);
|
||||
|
||||
err = bpf_prog_test_run_opts(prog_fd, &tattrs);
|
||||
ASSERT_OK(err) TH_LOG("error while calling bpf_prog_test_run_opts");
|
||||
|
||||
ASSERT_EQ(args.retval, 2);
|
||||
|
||||
ASSERT_EQ(args.data[1], 2);
|
||||
}
|
||||
|
||||
static int libbpf_print_fn(enum libbpf_print_level level,
|
||||
const char *format, va_list args)
|
||||
{
|
||||
|
@ -52,3 +52,39 @@ int attach_prog(struct attach_prog_args *ctx)
|
||||
0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct hid_hw_request_syscall_args {
|
||||
/* data needs to come at offset 0 so we can use it in calls */
|
||||
__u8 data[10];
|
||||
unsigned int hid;
|
||||
int retval;
|
||||
size_t size;
|
||||
enum hid_report_type type;
|
||||
__u8 request_type;
|
||||
};
|
||||
|
||||
SEC("syscall")
|
||||
int hid_user_raw_request(struct hid_hw_request_syscall_args *args)
|
||||
{
|
||||
struct hid_bpf_ctx *ctx;
|
||||
const size_t size = args->size;
|
||||
int i, ret = 0;
|
||||
|
||||
if (size > sizeof(args->data))
|
||||
return -7; /* -E2BIG */
|
||||
|
||||
ctx = hid_bpf_allocate_context(args->hid);
|
||||
if (!ctx)
|
||||
return -1; /* EPERM check */
|
||||
|
||||
ret = hid_bpf_hw_request(ctx,
|
||||
args->data,
|
||||
size,
|
||||
args->type,
|
||||
args->request_type);
|
||||
args->retval = ret;
|
||||
|
||||
hid_bpf_release_context(ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -10,5 +10,12 @@ extern __u8 *hid_bpf_get_data(struct hid_bpf_ctx *ctx,
|
||||
unsigned int offset,
|
||||
const size_t __sz) __ksym;
|
||||
extern int hid_bpf_attach_prog(unsigned int hid_id, int prog_fd, u32 flags) __ksym;
|
||||
extern struct hid_bpf_ctx *hid_bpf_allocate_context(unsigned int hid_id) __ksym;
|
||||
extern void hid_bpf_release_context(struct hid_bpf_ctx *ctx) __ksym;
|
||||
extern int hid_bpf_hw_request(struct hid_bpf_ctx *ctx,
|
||||
__u8 *data,
|
||||
size_t buf__sz,
|
||||
enum hid_report_type type,
|
||||
enum hid_class_request reqtype) __ksym;
|
||||
|
||||
#endif /* __HID_BPF_HELPERS_H */
|
||||
|
Loading…
Reference in New Issue
Block a user