// SPDX-License-Identifier: GPL-2.0
/*
 * Allowlist of PCI drivers that are allowed to bind to external devices
 */

#include <linux/ctype.h>
#include <linux/module.h>
#include <linux/pci.h>
#include "pci.h"

/*
 * Parameter to essentially disable allowlist code (thus allow all drivers to
 * connect to any external PCI devices).
 */
static bool trust_external_pci_devices;
core_param(trust_external_pci_devices, trust_external_pci_devices, bool, 0444);

/* Driver allowlist */
struct allowlist_entry {
	const char *drvr_name;
	struct list_head node;
};

static LIST_HEAD(allowlist);
static DECLARE_RWSEM(allowlist_sem);

#define TRUNCATED	"...<truncated>\n"

/*
 * Locks down the binding of drivers to untrusted devices
 * (No PCI drivers to bind to any new untrusted PCI device)
 */
static bool drivers_allowlist_lockdown = true;
static DECLARE_RWSEM(lockdown_sem);

static ssize_t drivers_allowlist_show(struct bus_type *bus, char *buf)
{
	size_t count = 0;
	struct allowlist_entry *entry;

	down_read(&allowlist_sem);
	list_for_each_entry(entry, &allowlist, node) {
		if (count + strlen(entry->drvr_name) + sizeof(TRUNCATED) <
		    PAGE_SIZE) {
			count += snprintf(buf + count, PAGE_SIZE - count,
					  "%s\n", entry->drvr_name);
		} else {
			count += snprintf(buf + count, PAGE_SIZE - count,
					  TRUNCATED);
			break;
		}
	}
	up_read(&allowlist_sem);
	return count;
}

static ssize_t drivers_allowlist_store(struct bus_type *bus, const char *buf,
				       size_t count)
{
	struct allowlist_entry *entry;
	ssize_t ret = count;
	unsigned int i;
	char *drv;

	if (!count)
		return -EINVAL;

	drv = kstrndup(buf, count, GFP_KERNEL);
	if (!drv)
		return -ENOMEM;

	/* Remove any trailing white spaces */
	strim(drv);
	if (!*drv) {
		ret = -EINVAL;
		goto out_kfree;
	}

	/* Driver names cannot have special characters */
	for (i = 0; i < strlen(drv); i++)
		if (!isalnum(drv[i]) && drv[i] != '_') {
			ret = -EINVAL;
			goto out_kfree;
		}

	down_write(&allowlist_sem);

	/* Lookup in the allowlist */
	list_for_each_entry(entry, &allowlist, node)
		if (!strcmp(drv, entry->drvr_name)) {
			ret = -EEXIST;
			goto out_release_sem;
		}

	/* Add a driver to the allowlist */
	entry = kmalloc(sizeof(*entry), GFP_KERNEL);
	if (!entry) {
		ret = -ENOMEM;
		goto out_release_sem;
	}
	entry->drvr_name = drv;
	list_add_tail(&entry->node, &allowlist);
	up_write(&allowlist_sem);
	return ret;

out_release_sem:
	up_write(&allowlist_sem);
out_kfree:
	kfree(drv);
	return ret;
}
static BUS_ATTR_RW(drivers_allowlist);

static ssize_t drivers_allowlist_lockdown_show(struct bus_type *bus, char *buf)
{
	int ret;

	down_read(&lockdown_sem);
	ret = sprintf(buf, "%u\n", drivers_allowlist_lockdown);
	up_read(&lockdown_sem);

	return ret;
}

static ssize_t
drivers_allowlist_lockdown_store(struct bus_type *bus, const char *buf,
				 size_t count)
{
	bool lockdown, state_changed = false;
	struct pci_dev *dev = NULL;

	if (strtobool(buf, &lockdown))
		return -EINVAL;

	down_write(&lockdown_sem);
	if (drivers_allowlist_lockdown != lockdown) {
		drivers_allowlist_lockdown = lockdown;
		state_changed = true;
	}
	up_write(&lockdown_sem);

	if (state_changed && !lockdown) {
		/* Attach any devices blocked earlier, subject to allowlist */
		for_each_pci_dev(dev) {
			if (dev_is_removable(&dev->dev) &&
			    !device_attach(&dev->dev))
				pci_dbg(dev, "No driver\n");
		}
	}
	return count;
}
static BUS_ATTR_RW(drivers_allowlist_lockdown);

static int __init pci_drivers_allowlist_init(void)
{
	int ret;

	if (trust_external_pci_devices)
		return 0;

	ret = bus_create_file(&pci_bus_type, &bus_attr_drivers_allowlist);
	if (ret) {
		pr_err("%s: failed to create allowlist in sysfs\n", __func__);
		return ret;
	}

	ret = bus_create_file(&pci_bus_type,
			      &bus_attr_drivers_allowlist_lockdown);
	if (ret) {
		pr_err("%s: failed to create allowlist_lockdown\n", __func__);
		bus_remove_file(&pci_bus_type, &bus_attr_drivers_allowlist);
	}
	return ret;
}
late_initcall(pci_drivers_allowlist_init);

static bool pci_driver_is_allowed(const char *name)
{
	struct allowlist_entry *entry;

	down_read(&allowlist_sem);
	list_for_each_entry(entry, &allowlist, node) {
		if (!strcmp(name, entry->drvr_name)) {
			up_read(&allowlist_sem);
			return true;
		}
	}
	up_read(&allowlist_sem);
	return false;
}

bool pci_allowed_to_attach(struct pci_driver *drv, struct pci_dev *dev)
{
	char event[16], drvr[32], *reason;
	char *udev_env[] = { event, drvr, NULL };

	snprintf(drvr, sizeof(drvr), "DRVR=%s", drv->name);

	/* Bypass Allowlist code, if platform wants so */
	if (trust_external_pci_devices) {
		reason = "trust_external_pci_devices";
		goto allowed;
	}

	/* Allow trusted devices */
	if (!dev_is_removable(&dev->dev)) {
		reason = "trusted device";
		goto allowed;
	}

	/* Don't allow any driver attaches, if locked down */
	down_read(&lockdown_sem);
	if (drivers_allowlist_lockdown) {
		up_read(&lockdown_sem);
		reason = "drivers_allowlist_lockdown enforced";
		goto not_allowed;
	}
	up_read(&lockdown_sem);

	/* Allow if driver is in allowlist */
	if (pci_driver_is_allowed(drv->name)) {
		reason = "drvr in allowlist";
		goto allowed;
	}
	reason = "drvr not in allowlist";

not_allowed:
	pci_err(dev, "attach not allowed to drvr %s [%s]\n", drv->name, reason);
	snprintf(event, sizeof(event), "EVENT=BLOCKED");
	kobject_uevent_env(&dev->dev.kobj, KOBJ_CHANGE, udev_env);
	return false;

allowed:
	pci_info(dev, "attach allowed to drvr %s [%s]\n", drv->name, reason);
	snprintf(event, sizeof(event), "EVENT=ALLOWED");
	kobject_uevent_env(&dev->dev.kobj, KOBJ_CHANGE, udev_env);
	return true;
}
