// SPDX-License-Identifier: GPL-2.0
/*
 * fail_function.c: Function-based error injection
 */
#include <linux/error-injection.h>
#include <linux/debugfs.h>
#include <linux/fault-inject.h>
#include <linux/kallsyms.h>
#include <linux/kprobes.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/slab.h>
#include <linux/uaccess.h>

static int fei_kprobe_handler(struct kprobe *kp, struct pt_regs *regs);

static void fei_post_handler(struct kprobe *kp, struct pt_regs *regs,
			     unsigned long flags)
{
	/*
	 * A dummy post handler is required to prohibit optimizing, because
	 * jump optimization does not support execution path overriding.
	 */
}

struct fei_attr {
	struct list_head list;
	struct kprobe kp;
	unsigned long retval;
};
static DEFINE_MUTEX(fei_lock);
static LIST_HEAD(fei_attr_list);
static DECLARE_FAULT_ATTR(fei_fault_attr);
static struct dentry *fei_debugfs_dir;

static unsigned long adjust_error_retval(unsigned long addr, unsigned long retv)
{
	switch (get_injectable_error_type(addr)) {
	case EI_ETYPE_NULL:
		return 0;
	case EI_ETYPE_ERRNO:
		if (retv < (unsigned long)-MAX_ERRNO)
			return (unsigned long)-EINVAL;
		break;
	case EI_ETYPE_ERRNO_NULL:
		if (retv != 0 && retv < (unsigned long)-MAX_ERRNO)
			return (unsigned long)-EINVAL;
		break;
	case EI_ETYPE_TRUE:
		return 1;
	}

	return retv;
}

static struct fei_attr *fei_attr_new(const char *sym, unsigned long addr)
{
	struct fei_attr *attr;

	attr = kzalloc(sizeof(*attr), GFP_KERNEL);
	if (attr) {
		attr->kp.symbol_name = kstrdup(sym, GFP_KERNEL);
		if (!attr->kp.symbol_name) {
			kfree(attr);
			return NULL;
		}
		attr->kp.pre_handler = fei_kprobe_handler;
		attr->kp.post_handler = fei_post_handler;
		attr->retval = adjust_error_retval(addr, 0);
		INIT_LIST_HEAD(&attr->list);
	}
	return attr;
}

static void fei_attr_free(struct fei_attr *attr)
{
	if (attr) {
		kfree(attr->kp.symbol_name);
		kfree(attr);
	}
}

static struct fei_attr *fei_attr_lookup(const char *sym)
{
	struct fei_attr *attr;

	list_for_each_entry(attr, &fei_attr_list, list) {
		if (!strcmp(attr->kp.symbol_name, sym))
			return attr;
	}

	return NULL;
}

static bool fei_attr_is_valid(struct fei_attr *_attr)
{
	struct fei_attr *attr;

	list_for_each_entry(attr, &fei_attr_list, list) {
		if (attr == _attr)
			return true;
	}

	return false;
}

static int fei_retval_set(void *data, u64 val)
{
	struct fei_attr *attr = data;
	unsigned long retv = (unsigned long)val;
	int err = 0;

	mutex_lock(&fei_lock);
	/*
	 * Since this operation can be done after retval file is removed,
	 * It is safer to check the attr is still valid before accessing
	 * its member.
	 */
	if (!fei_attr_is_valid(attr)) {
		err = -ENOENT;
		goto out;
	}

	if (attr->kp.addr) {
		if (adjust_error_retval((unsigned long)attr->kp.addr,
					val) != retv)
			err = -EINVAL;
	}
	if (!err)
		attr->retval = val;
out:
	mutex_unlock(&fei_lock);

	return err;
}

static int fei_retval_get(void *data, u64 *val)
{
	struct fei_attr *attr = data;
	int err = 0;

	mutex_lock(&fei_lock);
	/* Here we also validate @attr to ensure it still exists. */
	if (!fei_attr_is_valid(attr))
		err = -ENOENT;
	else
		*val = attr->retval;
	mutex_unlock(&fei_lock);

	return err;
}
DEFINE_DEBUGFS_ATTRIBUTE(fei_retval_ops, fei_retval_get, fei_retval_set,
			 "%llx\n");

static void fei_debugfs_add_attr(struct fei_attr *attr)
{
	struct dentry *dir;

	dir = debugfs_create_dir(attr->kp.symbol_name, fei_debugfs_dir);

	debugfs_create_file("retval", 0600, dir, attr, &fei_retval_ops);
}

static void fei_debugfs_remove_attr(struct fei_attr *attr)
{
	struct dentry *dir;

	dir = debugfs_lookup(attr->kp.symbol_name, fei_debugfs_dir);
	debugfs_remove_recursive(dir);
}

static int fei_kprobe_handler(struct kprobe *kp, struct pt_regs *regs)
{
	struct fei_attr *attr = container_of(kp, struct fei_attr, kp);

	if (should_fail(&fei_fault_attr, 1)) {
		regs_set_return_value(regs, attr->retval);
		override_function_with_return(regs);
		return 1;
	}

	return 0;
}
NOKPROBE_SYMBOL(fei_kprobe_handler)

static void *fei_seq_start(struct seq_file *m, loff_t *pos)
{
	mutex_lock(&fei_lock);
	return seq_list_start(&fei_attr_list, *pos);
}

static void fei_seq_stop(struct seq_file *m, void *v)
{
	mutex_unlock(&fei_lock);
}

static void *fei_seq_next(struct seq_file *m, void *v, loff_t *pos)
{
	return seq_list_next(v, &fei_attr_list, pos);
}

static int fei_seq_show(struct seq_file *m, void *v)
{
	struct fei_attr *attr = list_entry(v, struct fei_attr, list);

	seq_printf(m, "%ps\n", attr->kp.addr);
	return 0;
}

static const struct seq_operations fei_seq_ops = {
	.start	= fei_seq_start,
	.next	= fei_seq_next,
	.stop	= fei_seq_stop,
	.show	= fei_seq_show,
};

static int fei_open(struct inode *inode, struct file *file)
{
	return seq_open(file, &fei_seq_ops);
}

static void fei_attr_remove(struct fei_attr *attr)
{
	fei_debugfs_remove_attr(attr);
	unregister_kprobe(&attr->kp);
	list_del(&attr->list);
	fei_attr_free(attr);
}

static void fei_attr_remove_all(void)
{
	struct fei_attr *attr, *n;

	list_for_each_entry_safe(attr, n, &fei_attr_list, list) {
		fei_attr_remove(attr);
	}
}

static ssize_t fei_write(struct file *file, const char __user *buffer,
			 size_t count, loff_t *ppos)
{
	struct fei_attr *attr;
	unsigned long addr;
	char *buf, *sym;
	int ret;

	/* cut off if it is too long */
	if (count > KSYM_NAME_LEN)
		count = KSYM_NAME_LEN;
	buf = kmalloc(count + 1, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

	if (copy_from_user(buf, buffer, count)) {
		ret = -EFAULT;
		goto out_free;
	}
	buf[count] = '\0';
	sym = strstrip(buf);

	mutex_lock(&fei_lock);

	/* Writing just spaces will remove all injection points */
	if (sym[0] == '\0') {
		fei_attr_remove_all();
		ret = count;
		goto out;
	}
	/* Writing !function will remove one injection point */
	if (sym[0] == '!') {
		attr = fei_attr_lookup(sym + 1);
		if (!attr) {
			ret = -ENOENT;
			goto out;
		}
		fei_attr_remove(attr);
		ret = count;
		goto out;
	}

	addr = kallsyms_lookup_name(sym);
	if (!addr) {
		ret = -EINVAL;
		goto out;
	}
	if (!within_error_injection_list(addr)) {
		ret = -ERANGE;
		goto out;
	}
	if (fei_attr_lookup(sym)) {
		ret = -EBUSY;
		goto out;
	}
	attr = fei_attr_new(sym, addr);
	if (!attr) {
		ret = -ENOMEM;
		goto out;
	}

	ret = register_kprobe(&attr->kp);
	if (!ret)
		fei_debugfs_add_attr(attr);
	if (ret < 0)
		fei_attr_remove(attr);
	else {
		list_add_tail(&attr->list, &fei_attr_list);
		ret = count;
	}
out:
	mutex_unlock(&fei_lock);
out_free:
	kfree(buf);
	return ret;
}

static const struct file_operations fei_ops = {
	.open =		fei_open,
	.read =		seq_read,
	.write =	fei_write,
	.llseek =	seq_lseek,
	.release =	seq_release,
};

static int __init fei_debugfs_init(void)
{
	struct dentry *dir;

	dir = fault_create_debugfs_attr("fail_function", NULL,
					&fei_fault_attr);
	if (IS_ERR(dir))
		return PTR_ERR(dir);

	/* injectable attribute is just a symlink of error_inject/list */
	debugfs_create_symlink("injectable", dir, "../error_injection/list");

	debugfs_create_file("inject", 0600, dir, NULL, &fei_ops);

	fei_debugfs_dir = dir;

	return 0;
}

late_initcall(fei_debugfs_init);
