// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2022 Red hat */
#include "hid_bpf_helpers.h"

char _license[] SEC("license") = "GPL";

struct attach_prog_args {
	int prog_fd;
	unsigned int hid;
	int retval;
	int insert_head;
};

__u64 callback_check = 52;
__u64 callback2_check = 52;

SEC("?struct_ops/hid_device_event")
int BPF_PROG(hid_first_event, struct hid_bpf_ctx *hid_ctx, enum hid_report_type type)
{
	__u8 *rw_data = hid_bpf_get_data(hid_ctx, 0 /* offset */, 3 /* size */);

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

	callback_check = rw_data[1];

	rw_data[2] = rw_data[1] + 5;

	return hid_ctx->size;
}

SEC(".struct_ops.link")
struct hid_bpf_ops first_event = {
	.hid_device_event = (void *)hid_first_event,
	.hid_id = 2,
};

int __hid_subprog_first_event(struct hid_bpf_ctx *hid_ctx, enum hid_report_type type)
{
	__u8 *rw_data = hid_bpf_get_data(hid_ctx, 0 /* offset */, 3 /* size */);

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

	rw_data[2] = rw_data[1] + 5;

	return hid_ctx->size;
}

SEC("?struct_ops/hid_device_event")
int BPF_PROG(hid_subprog_first_event, struct hid_bpf_ctx *hid_ctx, enum hid_report_type type)
{
	return __hid_subprog_first_event(hid_ctx, type);
}

SEC(".struct_ops.link")
struct hid_bpf_ops subprog_first_event = {
	.hid_device_event = (void *)hid_subprog_first_event,
	.hid_id = 2,
};

SEC("?struct_ops/hid_device_event")
int BPF_PROG(hid_second_event, struct hid_bpf_ctx *hid_ctx, enum hid_report_type type)
{
	__u8 *rw_data = hid_bpf_get_data(hid_ctx, 0 /* offset */, 4 /* size */);

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

	rw_data[3] = rw_data[2] + 5;

	return hid_ctx->size;
}

SEC(".struct_ops.link")
struct hid_bpf_ops second_event = {
	.hid_device_event = (void *)hid_second_event,
};

SEC("?struct_ops/hid_device_event")
int BPF_PROG(hid_change_report_id, struct hid_bpf_ctx *hid_ctx, enum hid_report_type type)
{
	__u8 *rw_data = hid_bpf_get_data(hid_ctx, 0 /* offset */, 3 /* size */);

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

	rw_data[0] = 2;

	return 9;
}

SEC(".struct_ops.link")
struct hid_bpf_ops change_report_id = {
	.hid_device_event = (void *)hid_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];
	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;
}

SEC("syscall")
int hid_user_output_report(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_output_report(ctx,
				       args->data,
				       size);
	args->retval = ret;

	hid_bpf_release_context(ctx);

	return 0;
}

SEC("syscall")
int hid_user_input_report(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_input_report(ctx, HID_INPUT_REPORT, args->data, size);
	args->retval = ret;

	hid_bpf_release_context(ctx);

	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 */
};

/*
 * the following program is marked as sleepable (struct_ops.s).
 * This is not strictly mandatory but is a nice test for
 * sleepable struct_ops
 */
SEC("?struct_ops.s/hid_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;
}

SEC(".struct_ops.link")
struct hid_bpf_ops rdesc_fixup = {
	.hid_rdesc_fixup = (void *)hid_rdesc_fixup,
};

SEC("?struct_ops/hid_device_event")
int BPF_PROG(hid_test_insert1, struct hid_bpf_ctx *hid_ctx, enum hid_report_type type)
{
	__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(".struct_ops.link")
struct hid_bpf_ops test_insert1 = {
	.hid_device_event = (void *)hid_test_insert1,
	.flags = BPF_F_BEFORE,
};

SEC("?struct_ops/hid_device_event")
int BPF_PROG(hid_test_insert2, struct hid_bpf_ctx *hid_ctx, enum hid_report_type type)
{
	__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(".struct_ops.link")
struct hid_bpf_ops test_insert2 = {
	.hid_device_event = (void *)hid_test_insert2,
};

SEC("?struct_ops/hid_device_event")
int BPF_PROG(hid_test_insert3, struct hid_bpf_ctx *hid_ctx, enum hid_report_type type)
{
	__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;
}

SEC(".struct_ops.link")
struct hid_bpf_ops test_insert3 = {
	.hid_device_event = (void *)hid_test_insert3,
};

SEC("?struct_ops/hid_hw_request")
int BPF_PROG(hid_test_filter_raw_request, struct hid_bpf_ctx *hctx, unsigned char reportnum,
	     enum hid_report_type rtype, enum hid_class_request reqtype, __u64 source)
{
	return -20;
}

SEC(".struct_ops.link")
struct hid_bpf_ops test_filter_raw_request = {
	.hid_hw_request = (void *)hid_test_filter_raw_request,
};

static struct file *current_file;

SEC("fentry/hidraw_open")
int BPF_PROG(hidraw_open, struct inode *inode, struct file *file)
{
	current_file = file;
	return 0;
}

SEC("?struct_ops.s/hid_hw_request")
int BPF_PROG(hid_test_hidraw_raw_request, struct hid_bpf_ctx *hctx, unsigned char reportnum,
	     enum hid_report_type rtype, enum hid_class_request reqtype, __u64 source)
{
	__u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, 3 /* size */);
	int ret;

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

	/* check if the incoming request comes from our hidraw operation */
	if (source == (__u64)current_file) {
		data[0] = reportnum;

		ret = hid_bpf_hw_request(hctx, data, 2, rtype, reqtype);
		if (ret != 2)
			return -1;
		data[0] = reportnum + 1;
		data[1] = reportnum + 2;
		data[2] = reportnum + 3;
		return 3;
	}

	return 0;
}

SEC(".struct_ops.link")
struct hid_bpf_ops test_hidraw_raw_request = {
	.hid_hw_request = (void *)hid_test_hidraw_raw_request,
};

SEC("?struct_ops.s/hid_hw_request")
int BPF_PROG(hid_test_infinite_loop_raw_request, struct hid_bpf_ctx *hctx, unsigned char reportnum,
	     enum hid_report_type rtype, enum hid_class_request reqtype, __u64 source)
{
	__u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, 3 /* size */);
	int ret;

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

	/* always forward the request as-is to the device, hid-bpf should prevent
	 * infinite loops.
	 */
	data[0] = reportnum;

	ret = hid_bpf_hw_request(hctx, data, 2, rtype, reqtype);
	if (ret == 2)
		return 3;

	return 0;
}

SEC(".struct_ops.link")
struct hid_bpf_ops test_infinite_loop_raw_request = {
	.hid_hw_request = (void *)hid_test_infinite_loop_raw_request,
};

SEC("?struct_ops/hid_hw_output_report")
int BPF_PROG(hid_test_filter_output_report, struct hid_bpf_ctx *hctx, unsigned char reportnum,
	     enum hid_report_type rtype, enum hid_class_request reqtype, __u64 source)
{
	return -25;
}

SEC(".struct_ops.link")
struct hid_bpf_ops test_filter_output_report = {
	.hid_hw_output_report = (void *)hid_test_filter_output_report,
};

SEC("?struct_ops.s/hid_hw_output_report")
int BPF_PROG(hid_test_hidraw_output_report, struct hid_bpf_ctx *hctx, __u64 source)
{
	__u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, 3 /* size */);
	int ret;

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

	/* check if the incoming request comes from our hidraw operation */
	if (source == (__u64)current_file)
		return hid_bpf_hw_output_report(hctx, data, 2);

	return 0;
}

SEC(".struct_ops.link")
struct hid_bpf_ops test_hidraw_output_report = {
	.hid_hw_output_report = (void *)hid_test_hidraw_output_report,
};

SEC("?struct_ops.s/hid_hw_output_report")
int BPF_PROG(hid_test_infinite_loop_output_report, struct hid_bpf_ctx *hctx, __u64 source)
{
	__u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, 3 /* size */);
	int ret;

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

	/* always forward the request as-is to the device, hid-bpf should prevent
	 * infinite loops.
	 */

	ret = hid_bpf_hw_output_report(hctx, data, 2);
	if (ret == 2)
		return 2;

	return 0;
}

SEC(".struct_ops.link")
struct hid_bpf_ops test_infinite_loop_output_report = {
	.hid_hw_output_report = (void *)hid_test_infinite_loop_output_report,
};

struct elem {
	struct bpf_wq work;
};

struct {
	__uint(type, BPF_MAP_TYPE_HASH);
	__uint(max_entries, 1);
	__type(key, int);
	__type(value, struct elem);
} hmap SEC(".maps");

static int wq_cb_sleepable(void *map, int *key, void *work)
{
	__u8 buf[9] = {2, 3, 4, 5, 6, 7, 8, 9, 10};
	struct hid_bpf_ctx *hid_ctx;

	hid_ctx = hid_bpf_allocate_context(*key);
	if (!hid_ctx)
		return 0; /* EPERM check */

	hid_bpf_input_report(hid_ctx, HID_INPUT_REPORT, buf, sizeof(buf));

	hid_bpf_release_context(hid_ctx);

	return 0;
}

static int test_inject_input_report_callback(int *key)
{
	struct elem init = {}, *val;
	struct bpf_wq *wq;

	if (bpf_map_update_elem(&hmap, key, &init, 0))
		return -1;

	val = bpf_map_lookup_elem(&hmap, key);
	if (!val)
		return -2;

	wq = &val->work;
	if (bpf_wq_init(wq, &hmap, 0) != 0)
		return -3;

	if (bpf_wq_set_callback(wq, wq_cb_sleepable, 0))
		return -4;

	if (bpf_wq_start(wq, 0))
		return -5;

	return 0;
}

SEC("?struct_ops/hid_device_event")
int BPF_PROG(hid_test_multiply_events_wq, struct hid_bpf_ctx *hid_ctx, enum hid_report_type type)
{
	__u8 *data = hid_bpf_get_data(hid_ctx, 0 /* offset */, 9 /* size */);
	int hid = hid_ctx->hid->id;
	int ret;

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

	if (data[0] != 1)
		return 0;

	ret = test_inject_input_report_callback(&hid);
	if (ret)
		return ret;

	data[1] += 5;

	return 0;
}

SEC(".struct_ops.link")
struct hid_bpf_ops test_multiply_events_wq = {
	.hid_device_event = (void *)hid_test_multiply_events_wq,
};

SEC("?struct_ops/hid_device_event")
int BPF_PROG(hid_test_multiply_events, struct hid_bpf_ctx *hid_ctx, enum hid_report_type type)
{
	__u8 *data = hid_bpf_get_data(hid_ctx, 0 /* offset */, 9 /* size */);
	__u8 buf[9];
	int ret;

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

	if (data[0] != 1)
		return 0;

	/*
	 * we have to use an intermediate buffer as hid_bpf_input_report
	 * will memset data to \0
	 */
	__builtin_memcpy(buf, data, sizeof(buf));

	buf[0] = 2;
	buf[1] += 5;
	ret = hid_bpf_try_input_report(hid_ctx, HID_INPUT_REPORT, buf, sizeof(buf));
	if (ret < 0)
		return ret;

	/*
	 * In real world we should reset the original buffer as data might be garbage now,
	 * but it actually now has the content of 'buf'
	 */
	data[1] += 5;

	return 9;
}

SEC(".struct_ops.link")
struct hid_bpf_ops test_multiply_events = {
	.hid_device_event = (void *)hid_test_multiply_events,
};

SEC("?struct_ops/hid_device_event")
int BPF_PROG(hid_test_infinite_loop_input_report, struct hid_bpf_ctx *hctx,
	     enum hid_report_type report_type, __u64 source)
{
	__u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, 6 /* size */);
	__u8 buf[6];

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

	/*
	 * we have to use an intermediate buffer as hid_bpf_input_report
	 * will memset data to \0
	 */
	__builtin_memcpy(buf, data, sizeof(buf));

	/* always forward the request as-is to the device, hid-bpf should prevent
	 * infinite loops.
	 * the return value is ignored so the event is passing to userspace.
	 */

	hid_bpf_try_input_report(hctx, report_type, buf, sizeof(buf));

	/* each time we process the event, we increment by one data[1]:
	 * after each successful call to hid_bpf_try_input_report, buf
	 * has been memcopied into data by the kernel.
	 */
	data[1] += 1;

	return 0;
}

SEC(".struct_ops.link")
struct hid_bpf_ops test_infinite_loop_input_report = {
	.hid_device_event = (void *)hid_test_infinite_loop_input_report,
};
