// SPDX-License-Identifier: GPL-2.0-only

/*
 *  HID-BPF support for Linux
 *
 *  Copyright (c) 2022 Benjamin Tissoires
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/bitops.h>
#include <linux/btf.h>
#include <linux/btf_ids.h>
#include <linux/filter.h>
#include <linux/hid.h>
#include <linux/hid_bpf.h>
#include <linux/init.h>
#include <linux/kfifo.h>
#include <linux/minmax.h>
#include <linux/module.h>
#include <linux/workqueue.h>
#include "hid_bpf_dispatch.h"
#include "entrypoints/entrypoints.lskel.h"

struct hid_bpf_ops *hid_bpf_ops;
EXPORT_SYMBOL(hid_bpf_ops);

/**
 * hid_bpf_device_event - Called whenever an event is coming in from the device
 *
 * @ctx: The HID-BPF context
 *
 * @return %0 on success and keep processing; a positive value to change the
 * incoming size buffer; a negative error code to interrupt the processing
 * of this event
 *
 * Declare an %fmod_ret tracing bpf program to this function and attach this
 * program through hid_bpf_attach_prog() to have this helper called for
 * any incoming event from the device itself.
 *
 * The function is called while on IRQ context, so we can not sleep.
 */
/* never used by the kernel but declared so we can load and attach a tracepoint */
__weak noinline int hid_bpf_device_event(struct hid_bpf_ctx *ctx)
{
	return 0;
}

u8 *
dispatch_hid_bpf_device_event(struct hid_device *hdev, enum hid_report_type type, u8 *data,
			      u32 *size, int interrupt)
{
	struct hid_bpf_ctx_kern ctx_kern = {
		.ctx = {
			.hid = hdev,
			.report_type = type,
			.allocated_size = hdev->bpf.allocated_data,
			.size = *size,
		},
		.data = hdev->bpf.device_data,
	};
	int ret;

	if (type >= HID_REPORT_TYPES)
		return ERR_PTR(-EINVAL);

	/* no program has been attached yet */
	if (!hdev->bpf.device_data)
		return data;

	memset(ctx_kern.data, 0, hdev->bpf.allocated_data);
	memcpy(ctx_kern.data, data, *size);

	ret = hid_bpf_prog_run(hdev, HID_BPF_PROG_TYPE_DEVICE_EVENT, &ctx_kern);
	if (ret < 0)
		return ERR_PTR(ret);

	if (ret) {
		if (ret > ctx_kern.ctx.allocated_size)
			return ERR_PTR(-EINVAL);

		*size = ret;
	}

	return ctx_kern.data;
}
EXPORT_SYMBOL_GPL(dispatch_hid_bpf_device_event);

/**
 * hid_bpf_rdesc_fixup - Called when the probe function parses the report
 * descriptor of the HID device
 *
 * @ctx: The HID-BPF context
 *
 * @return 0 on success and keep processing; a positive value to change the
 * incoming size buffer; a negative error code to interrupt the processing
 * of this event
 *
 * Declare an %fmod_ret tracing bpf program to this function and attach this
 * program through hid_bpf_attach_prog() to have this helper called before any
 * parsing of the report descriptor by HID.
 */
/* never used by the kernel but declared so we can load and attach a tracepoint */
__weak noinline int hid_bpf_rdesc_fixup(struct hid_bpf_ctx *ctx)
{
	return 0;
}

u8 *call_hid_bpf_rdesc_fixup(struct hid_device *hdev, u8 *rdesc, unsigned int *size)
{
	int ret;
	struct hid_bpf_ctx_kern ctx_kern = {
		.ctx = {
			.hid = hdev,
			.size = *size,
			.allocated_size = HID_MAX_DESCRIPTOR_SIZE,
		},
	};

	ctx_kern.data = kzalloc(ctx_kern.ctx.allocated_size, GFP_KERNEL);
	if (!ctx_kern.data)
		goto ignore_bpf;

	memcpy(ctx_kern.data, rdesc, min_t(unsigned int, *size, HID_MAX_DESCRIPTOR_SIZE));

	ret = hid_bpf_prog_run(hdev, HID_BPF_PROG_TYPE_RDESC_FIXUP, &ctx_kern);
	if (ret < 0)
		goto ignore_bpf;

	if (ret) {
		if (ret > ctx_kern.ctx.allocated_size)
			goto ignore_bpf;

		*size = ret;
	}

	rdesc = krealloc(ctx_kern.data, *size, GFP_KERNEL);

	return rdesc;

 ignore_bpf:
	kfree(ctx_kern.data);
	return kmemdup(rdesc, *size, GFP_KERNEL);
}
EXPORT_SYMBOL_GPL(call_hid_bpf_rdesc_fixup);

/* Disables missing prototype warnings */
__bpf_kfunc_start_defs();

/**
 * hid_bpf_get_data - Get the kernel memory pointer associated with the context @ctx
 *
 * @ctx: The HID-BPF context
 * @offset: The offset within the memory
 * @rdwr_buf_size: the const size of the buffer
 *
 * @returns %NULL on error, an %__u8 memory pointer on success
 */
__bpf_kfunc __u8 *
hid_bpf_get_data(struct hid_bpf_ctx *ctx, unsigned int offset, const size_t rdwr_buf_size)
{
	struct hid_bpf_ctx_kern *ctx_kern;

	if (!ctx)
		return NULL;

	ctx_kern = container_of(ctx, struct hid_bpf_ctx_kern, ctx);

	if (rdwr_buf_size + offset > ctx->allocated_size)
		return NULL;

	return ctx_kern->data + offset;
}
__bpf_kfunc_end_defs();

/*
 * The following set contains all functions we agree BPF programs
 * can use.
 */
BTF_SET8_START(hid_bpf_kfunc_ids)
BTF_ID_FLAGS(func, hid_bpf_get_data, KF_RET_NULL)
BTF_SET8_END(hid_bpf_kfunc_ids)

static const struct btf_kfunc_id_set hid_bpf_kfunc_set = {
	.owner = THIS_MODULE,
	.set   = &hid_bpf_kfunc_ids,
};

static int device_match_id(struct device *dev, const void *id)
{
	struct hid_device *hdev = to_hid_device(dev);

	return hdev->id == *(int *)id;
}

static int __hid_bpf_allocate_data(struct hid_device *hdev, u8 **data, u32 *size)
{
	u8 *alloc_data;
	unsigned int i, j, max_report_len = 0;
	size_t alloc_size = 0;

	/* compute the maximum report length for this device */
	for (i = 0; i < HID_REPORT_TYPES; i++) {
		struct hid_report_enum *report_enum = hdev->report_enum + i;

		for (j = 0; j < HID_MAX_IDS; j++) {
			struct hid_report *report = report_enum->report_id_hash[j];

			if (report)
				max_report_len = max(max_report_len, hid_report_len(report));
		}
	}

	/*
	 * Give us a little bit of extra space and some predictability in the
	 * buffer length we create. This way, we can tell users that they can
	 * work on chunks of 64 bytes of memory without having the bpf verifier
	 * scream at them.
	 */
	alloc_size = DIV_ROUND_UP(max_report_len, 64) * 64;

	alloc_data = kzalloc(alloc_size, GFP_KERNEL);
	if (!alloc_data)
		return -ENOMEM;

	*data = alloc_data;
	*size = alloc_size;

	return 0;
}

static int hid_bpf_allocate_event_data(struct hid_device *hdev)
{
	/* hdev->bpf.device_data is already allocated, abort */
	if (hdev->bpf.device_data)
		return 0;

	return __hid_bpf_allocate_data(hdev, &hdev->bpf.device_data, &hdev->bpf.allocated_data);
}

int hid_bpf_reconnect(struct hid_device *hdev)
{
	if (!test_and_set_bit(ffs(HID_STAT_REPROBED), &hdev->status))
		return device_reprobe(&hdev->dev);

	return 0;
}

static int do_hid_bpf_attach_prog(struct hid_device *hdev, int prog_fd, struct bpf_prog *prog,
				  __u32 flags)
{
	int fd, err, prog_type;

	prog_type = hid_bpf_get_prog_attach_type(prog);
	if (prog_type < 0)
		return prog_type;

	if (prog_type >= HID_BPF_PROG_TYPE_MAX)
		return -EINVAL;

	if (prog_type == HID_BPF_PROG_TYPE_DEVICE_EVENT) {
		err = hid_bpf_allocate_event_data(hdev);
		if (err)
			return err;
	}

	fd = __hid_bpf_attach_prog(hdev, prog_type, prog_fd, prog, flags);
	if (fd < 0)
		return fd;

	if (prog_type == HID_BPF_PROG_TYPE_RDESC_FIXUP) {
		err = hid_bpf_reconnect(hdev);
		if (err) {
			close_fd(fd);
			return err;
		}
	}

	return fd;
}

/* Disables missing prototype warnings */
__bpf_kfunc_start_defs();

/**
 * hid_bpf_attach_prog - Attach the given @prog_fd to the given HID device
 *
 * @hid_id: the system unique identifier of the HID device
 * @prog_fd: an fd in the user process representing the program to attach
 * @flags: any logical OR combination of &enum hid_bpf_attach_flags
 *
 * @returns an fd of a bpf_link object on success (> %0), an error code otherwise.
 * Closing this fd will detach the program from the HID device (unless the bpf_link
 * is pinned to the BPF file system).
 */
/* called from syscall */
__bpf_kfunc int
hid_bpf_attach_prog(unsigned int hid_id, int prog_fd, __u32 flags)
{
	struct hid_device *hdev;
	struct bpf_prog *prog;
	struct device *dev;
	int err, fd;

	if (!hid_bpf_ops)
		return -EINVAL;

	if ((flags & ~HID_BPF_FLAG_MASK))
		return -EINVAL;

	dev = bus_find_device(hid_bpf_ops->bus_type, NULL, &hid_id, device_match_id);
	if (!dev)
		return -EINVAL;

	hdev = to_hid_device(dev);

	/*
	 * take a ref on the prog itself, it will be released
	 * on errors or when it'll be detached
	 */
	prog = bpf_prog_get(prog_fd);
	if (IS_ERR(prog)) {
		err = PTR_ERR(prog);
		goto out_dev_put;
	}

	fd = do_hid_bpf_attach_prog(hdev, prog_fd, prog, flags);
	if (fd < 0) {
		err = fd;
		goto out_prog_put;
	}

	return fd;

 out_prog_put:
	bpf_prog_put(prog);
 out_dev_put:
	put_device(dev);
	return err;
}

/**
 * hid_bpf_allocate_context - Allocate a context to the given HID device
 *
 * @hid_id: the system unique identifier of the HID device
 *
 * @returns A pointer to &struct hid_bpf_ctx on success, %NULL on error.
 */
__bpf_kfunc struct hid_bpf_ctx *
hid_bpf_allocate_context(unsigned int hid_id)
{
	struct hid_device *hdev;
	struct hid_bpf_ctx_kern *ctx_kern = NULL;
	struct device *dev;

	if (!hid_bpf_ops)
		return NULL;

	dev = bus_find_device(hid_bpf_ops->bus_type, NULL, &hid_id, device_match_id);
	if (!dev)
		return NULL;

	hdev = to_hid_device(dev);

	ctx_kern = kzalloc(sizeof(*ctx_kern), GFP_KERNEL);
	if (!ctx_kern) {
		put_device(dev);
		return NULL;
	}

	ctx_kern->ctx.hid = hdev;

	return &ctx_kern->ctx;
}

/**
 * hid_bpf_release_context - Release the previously allocated context @ctx
 *
 * @ctx: the HID-BPF context to release
 *
 */
__bpf_kfunc void
hid_bpf_release_context(struct hid_bpf_ctx *ctx)
{
	struct hid_bpf_ctx_kern *ctx_kern;
	struct hid_device *hid;

	ctx_kern = container_of(ctx, struct hid_bpf_ctx_kern, ctx);
	hid = (struct hid_device *)ctx_kern->ctx.hid; /* ignore const */

	kfree(ctx_kern);

	/* get_device() is called by bus_find_device() */
	put_device(&hid->dev);
}

/**
 * hid_bpf_hw_request - Communicate with a HID device
 *
 * @ctx: the HID-BPF context previously allocated in hid_bpf_allocate_context()
 * @buf: a %PTR_TO_MEM buffer
 * @buf__sz: the size of the data to transfer
 * @rtype: the type of the report (%HID_INPUT_REPORT, %HID_FEATURE_REPORT, %HID_OUTPUT_REPORT)
 * @reqtype: the type of the request (%HID_REQ_GET_REPORT, %HID_REQ_SET_REPORT, ...)
 *
 * @returns %0 on success, a negative error code otherwise.
 */
__bpf_kfunc int
hid_bpf_hw_request(struct hid_bpf_ctx *ctx, __u8 *buf, size_t buf__sz,
		   enum hid_report_type rtype, enum hid_class_request reqtype)
{
	struct hid_device *hdev;
	struct hid_report *report;
	struct hid_report_enum *report_enum;
	u8 *dma_data;
	u32 report_len;
	int ret;

	/* check arguments */
	if (!ctx || !hid_bpf_ops || !buf)
		return -EINVAL;

	switch (rtype) {
	case HID_INPUT_REPORT:
	case HID_OUTPUT_REPORT:
	case HID_FEATURE_REPORT:
		break;
	default:
		return -EINVAL;
	}

	switch (reqtype) {
	case HID_REQ_GET_REPORT:
	case HID_REQ_GET_IDLE:
	case HID_REQ_GET_PROTOCOL:
	case HID_REQ_SET_REPORT:
	case HID_REQ_SET_IDLE:
	case HID_REQ_SET_PROTOCOL:
		break;
	default:
		return -EINVAL;
	}

	if (buf__sz < 1)
		return -EINVAL;

	hdev = (struct hid_device *)ctx->hid; /* discard const */

	report_enum = hdev->report_enum + rtype;
	report = hid_bpf_ops->hid_get_report(report_enum, buf);
	if (!report)
		return -EINVAL;

	report_len = hid_report_len(report);

	if (buf__sz > report_len)
		buf__sz = report_len;

	dma_data = kmemdup(buf, buf__sz, GFP_KERNEL);
	if (!dma_data)
		return -ENOMEM;

	ret = hid_bpf_ops->hid_hw_raw_request(hdev,
					      dma_data[0],
					      dma_data,
					      buf__sz,
					      rtype,
					      reqtype);

	if (ret > 0)
		memcpy(buf, dma_data, ret);

	kfree(dma_data);
	return ret;
}
__bpf_kfunc_end_defs();

/* our HID-BPF entrypoints */
BTF_SET8_START(hid_bpf_fmodret_ids)
BTF_ID_FLAGS(func, hid_bpf_device_event)
BTF_ID_FLAGS(func, hid_bpf_rdesc_fixup)
BTF_ID_FLAGS(func, __hid_bpf_tail_call)
BTF_SET8_END(hid_bpf_fmodret_ids)

static const struct btf_kfunc_id_set hid_bpf_fmodret_set = {
	.owner = THIS_MODULE,
	.set   = &hid_bpf_fmodret_ids,
};

/* for syscall HID-BPF */
BTF_SET8_START(hid_bpf_syscall_kfunc_ids)
BTF_ID_FLAGS(func, hid_bpf_attach_prog)
BTF_ID_FLAGS(func, hid_bpf_allocate_context, KF_ACQUIRE | KF_RET_NULL)
BTF_ID_FLAGS(func, hid_bpf_release_context, KF_RELEASE)
BTF_ID_FLAGS(func, hid_bpf_hw_request)
BTF_SET8_END(hid_bpf_syscall_kfunc_ids)

static const struct btf_kfunc_id_set hid_bpf_syscall_kfunc_set = {
	.owner = THIS_MODULE,
	.set   = &hid_bpf_syscall_kfunc_ids,
};

int hid_bpf_connect_device(struct hid_device *hdev)
{
	struct hid_bpf_prog_list *prog_list;

	rcu_read_lock();
	prog_list = rcu_dereference(hdev->bpf.progs[HID_BPF_PROG_TYPE_DEVICE_EVENT]);
	rcu_read_unlock();

	/* only allocate BPF data if there are programs attached */
	if (!prog_list)
		return 0;

	return hid_bpf_allocate_event_data(hdev);
}
EXPORT_SYMBOL_GPL(hid_bpf_connect_device);

void hid_bpf_disconnect_device(struct hid_device *hdev)
{
	kfree(hdev->bpf.device_data);
	hdev->bpf.device_data = NULL;
	hdev->bpf.allocated_data = 0;
}
EXPORT_SYMBOL_GPL(hid_bpf_disconnect_device);

void hid_bpf_destroy_device(struct hid_device *hdev)
{
	if (!hdev)
		return;

	/* mark the device as destroyed in bpf so we don't reattach it */
	hdev->bpf.destroyed = true;

	__hid_bpf_destroy_device(hdev);
}
EXPORT_SYMBOL_GPL(hid_bpf_destroy_device);

void hid_bpf_device_init(struct hid_device *hdev)
{
	spin_lock_init(&hdev->bpf.progs_lock);
}
EXPORT_SYMBOL_GPL(hid_bpf_device_init);

static int __init hid_bpf_init(void)
{
	int err;

	/* Note: if we exit with an error any time here, we would entirely break HID, which
	 * is probably not something we want. So we log an error and return success.
	 *
	 * This is not a big deal: the syscall allowing to attach a BPF program to a HID device
	 * will not be available, so nobody will be able to use the functionality.
	 */

	err = register_btf_fmodret_id_set(&hid_bpf_fmodret_set);
	if (err) {
		pr_warn("error while registering fmodret entrypoints: %d", err);
		return 0;
	}

	err = hid_bpf_preload_skel();
	if (err) {
		pr_warn("error while preloading HID BPF dispatcher: %d", err);
		return 0;
	}

	/* register tracing kfuncs after we are sure we can load our preloaded bpf program */
	err = register_btf_kfunc_id_set(BPF_PROG_TYPE_TRACING, &hid_bpf_kfunc_set);
	if (err) {
		pr_warn("error while setting HID BPF tracing kfuncs: %d", err);
		return 0;
	}

	/* register syscalls after we are sure we can load our preloaded bpf program */
	err = register_btf_kfunc_id_set(BPF_PROG_TYPE_SYSCALL, &hid_bpf_syscall_kfunc_set);
	if (err) {
		pr_warn("error while setting HID BPF syscall kfuncs: %d", err);
		return 0;
	}

	return 0;
}

static void __exit hid_bpf_exit(void)
{
	/* HID depends on us, so if we hit that code, we are guaranteed that hid
	 * has been removed and thus we do not need to clear the HID devices
	 */
	hid_bpf_free_links_and_skel();
}

late_initcall(hid_bpf_init);
module_exit(hid_bpf_exit);
MODULE_AUTHOR("Benjamin Tissoires");
MODULE_LICENSE("GPL");
