// SPDX-License-Identifier: GPL-2.0
/*
 * mokvar-table.c
 *
 * Copyright (c) 2020 Red Hat
 * Author: Lenny Szubowicz <lszubowi@redhat.com>
 *
 * This module contains the kernel support for the Linux EFI Machine
 * Owner Key (MOK) variable configuration table, which is identified by
 * the LINUX_EFI_MOK_VARIABLE_TABLE_GUID.
 *
 * This EFI configuration table provides a more robust alternative to
 * EFI volatile variables by which an EFI boot loader can pass the
 * contents of the Machine Owner Key (MOK) certificate stores to the
 * kernel during boot. If both the EFI MOK config table and corresponding
 * EFI MOK variables are present, the table should be considered as
 * more authoritative.
 *
 * This module includes code that validates and maps the EFI MOK table,
 * if it's presence was detected very early in boot.
 *
 * Kernel interface routines are provided to walk through all the
 * entries in the MOK config table or to search for a specific named
 * entry.
 *
 * The contents of the individual named MOK config table entries are
 * made available to user space via read-only sysfs binary files under:
 *
 * /sys/firmware/efi/mok-variables/
 *
 */
#define pr_fmt(fmt) "mokvar: " fmt

#include <linux/capability.h>
#include <linux/efi.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/kobject.h>
#include <linux/list.h>
#include <linux/slab.h>

#include <asm/early_ioremap.h>

/*
 * The LINUX_EFI_MOK_VARIABLE_TABLE_GUID config table is a packed
 * sequence of struct efi_mokvar_table_entry, one for each named
 * MOK variable. The sequence is terminated by an entry with a
 * completely NULL name and 0 data size.
 *
 * efi_mokvar_table_size is set to the computed size of the
 * MOK config table by efi_mokvar_table_init(). This will be
 * non-zero if and only if the table if present and has been
 * validated by efi_mokvar_table_init().
 */
static size_t efi_mokvar_table_size;

/*
 * efi_mokvar_table_va is the kernel virtual address at which the
 * EFI MOK config table has been mapped by efi_mokvar_sysfs_init().
 */
static struct efi_mokvar_table_entry *efi_mokvar_table_va;

/*
 * Each /sys/firmware/efi/mok-variables/ sysfs file is represented by
 * an instance of struct efi_mokvar_sysfs_attr on efi_mokvar_sysfs_list.
 * bin_attr.private points to the associated EFI MOK config table entry.
 *
 * This list is created during boot and then remains unchanged.
 * So no synchronization is currently required to walk the list.
 */
struct efi_mokvar_sysfs_attr {
	struct bin_attribute bin_attr;
	struct list_head node;
};

static LIST_HEAD(efi_mokvar_sysfs_list);
static struct kobject *mokvar_kobj;

/*
 * efi_mokvar_table_init() - Early boot validation of EFI MOK config table
 *
 * If present, validate and compute the size of the EFI MOK variable
 * configuration table. This table may be provided by an EFI boot loader
 * as an alternative to ordinary EFI variables, due to platform-dependent
 * limitations. The memory occupied by this table is marked as reserved.
 *
 * This routine must be called before efi_free_boot_services() in order
 * to guarantee that it can mark the table as reserved.
 *
 * Implicit inputs:
 * efi.mokvar_table:	Physical address of EFI MOK variable config table
 *			or special value that indicates no such table.
 *
 * Implicit outputs:
 * efi_mokvar_table_size: Computed size of EFI MOK variable config table.
 *			The table is considered present and valid if this
 *			is non-zero.
 */
void __init efi_mokvar_table_init(void)
{
	efi_memory_desc_t md;
	void *va = NULL;
	unsigned long cur_offset = 0;
	unsigned long offset_limit;
	unsigned long map_size = 0;
	unsigned long map_size_needed = 0;
	unsigned long size;
	struct efi_mokvar_table_entry *mokvar_entry;
	int err;

	if (!efi_enabled(EFI_MEMMAP))
		return;

	if (efi.mokvar_table == EFI_INVALID_TABLE_ADDR)
		return;
	/*
	 * The EFI MOK config table must fit within a single EFI memory
	 * descriptor range.
	 */
	err = efi_mem_desc_lookup(efi.mokvar_table, &md);
	if (err) {
		pr_warn("EFI MOKvar config table is not within the EFI memory map\n");
		return;
	}

	offset_limit = efi_mem_desc_end(&md) - efi.mokvar_table;

	/*
	 * Validate the MOK config table. Since there is no table header
	 * from which we could get the total size of the MOK config table,
	 * we compute the total size as we validate each variably sized
	 * entry, remapping as necessary.
	 */
	err = -EINVAL;
	while (cur_offset + sizeof(*mokvar_entry) <= offset_limit) {
		mokvar_entry = va + cur_offset;
		map_size_needed = cur_offset + sizeof(*mokvar_entry);
		if (map_size_needed > map_size) {
			if (va)
				early_memunmap(va, map_size);
			/*
			 * Map a little more than the fixed size entry
			 * header, anticipating some data. It's safe to
			 * do so as long as we stay within current memory
			 * descriptor.
			 */
			map_size = min(map_size_needed + 2*EFI_PAGE_SIZE,
				       offset_limit);
			va = early_memremap(efi.mokvar_table, map_size);
			if (!va) {
				pr_err("Failed to map EFI MOKvar config table pa=0x%lx, size=%lu.\n",
				       efi.mokvar_table, map_size);
				return;
			}
			mokvar_entry = va + cur_offset;
		}

		/* Check for last sentinel entry */
		if (mokvar_entry->name[0] == '\0') {
			if (mokvar_entry->data_size != 0)
				break;
			err = 0;
			break;
		}

		/* Sanity check that the name is null terminated */
		size = strnlen(mokvar_entry->name,
			       sizeof(mokvar_entry->name));
		if (size >= sizeof(mokvar_entry->name))
			break;

		/* Advance to the next entry */
		cur_offset = map_size_needed + mokvar_entry->data_size;
	}

	if (va)
		early_memunmap(va, map_size);
	if (err) {
		pr_err("EFI MOKvar config table is not valid\n");
		return;
	}

	if (md.type == EFI_BOOT_SERVICES_DATA)
		efi_mem_reserve(efi.mokvar_table, map_size_needed);

	efi_mokvar_table_size = map_size_needed;
}

/*
 * efi_mokvar_entry_next() - Get next entry in the EFI MOK config table
 *
 * mokvar_entry:	Pointer to current EFI MOK config table entry
 *			or null. Null indicates get first entry.
 *			Passed by reference. This is updated to the
 *			same value as the return value.
 *
 * Returns:		Pointer to next EFI MOK config table entry
 *			or null, if there are no more entries.
 *			Same value is returned in the mokvar_entry
 *			parameter.
 *
 * This routine depends on the EFI MOK config table being entirely
 * mapped with it's starting virtual address in efi_mokvar_table_va.
 */
struct efi_mokvar_table_entry *efi_mokvar_entry_next(
			struct efi_mokvar_table_entry **mokvar_entry)
{
	struct efi_mokvar_table_entry *mokvar_cur;
	struct efi_mokvar_table_entry *mokvar_next;
	size_t size_cur;

	mokvar_cur = *mokvar_entry;
	*mokvar_entry = NULL;

	if (efi_mokvar_table_va == NULL)
		return NULL;

	if (mokvar_cur == NULL) {
		mokvar_next = efi_mokvar_table_va;
	} else {
		if (mokvar_cur->name[0] == '\0')
			return NULL;
		size_cur = sizeof(*mokvar_cur) + mokvar_cur->data_size;
		mokvar_next = (void *)mokvar_cur + size_cur;
	}

	if (mokvar_next->name[0] == '\0')
		return NULL;

	*mokvar_entry = mokvar_next;
	return mokvar_next;
}

/*
 * efi_mokvar_entry_find() - Find EFI MOK config entry by name
 *
 * name:	Name of the entry to look for.
 *
 * Returns:	Pointer to EFI MOK config table entry if found;
 *		null otherwise.
 *
 * This routine depends on the EFI MOK config table being entirely
 * mapped with it's starting virtual address in efi_mokvar_table_va.
 */
struct efi_mokvar_table_entry *efi_mokvar_entry_find(const char *name)
{
	struct efi_mokvar_table_entry *mokvar_entry = NULL;

	while (efi_mokvar_entry_next(&mokvar_entry)) {
		if (!strncmp(name, mokvar_entry->name,
			     sizeof(mokvar_entry->name)))
			return mokvar_entry;
	}
	return NULL;
}

/*
 * efi_mokvar_sysfs_read() - sysfs binary file read routine
 *
 * Returns:	Count of bytes read.
 *
 * Copy EFI MOK config table entry data for this mokvar sysfs binary file
 * to the supplied buffer, starting at the specified offset into mokvar table
 * entry data, for the specified count bytes. The copy is limited by the
 * amount of data in this mokvar config table entry.
 */
static ssize_t efi_mokvar_sysfs_read(struct file *file, struct kobject *kobj,
				 struct bin_attribute *bin_attr, char *buf,
				 loff_t off, size_t count)
{
	struct efi_mokvar_table_entry *mokvar_entry = bin_attr->private;

	if (!capable(CAP_SYS_ADMIN))
		return 0;

	if (off >= mokvar_entry->data_size)
		return 0;
	if (count >  mokvar_entry->data_size - off)
		count = mokvar_entry->data_size - off;

	memcpy(buf, mokvar_entry->data + off, count);
	return count;
}

/*
 * efi_mokvar_sysfs_init() - Map EFI MOK config table and create sysfs
 *
 * Map the EFI MOK variable config table for run-time use by the kernel
 * and create the sysfs entries in /sys/firmware/efi/mok-variables/
 *
 * This routine just returns if a valid EFI MOK variable config table
 * was not found earlier during boot.
 *
 * This routine must be called during a "middle" initcall phase, i.e.
 * after efi_mokvar_table_init() but before UEFI certs are loaded
 * during late init.
 *
 * Implicit inputs:
 * efi.mokvar_table:	Physical address of EFI MOK variable config table
 *			or special value that indicates no such table.
 *
 * efi_mokvar_table_size: Computed size of EFI MOK variable config table.
 *			The table is considered present and valid if this
 *			is non-zero.
 *
 * Implicit outputs:
 * efi_mokvar_table_va:	Start virtual address of the EFI MOK config table.
 */
static int __init efi_mokvar_sysfs_init(void)
{
	void *config_va;
	struct efi_mokvar_table_entry *mokvar_entry = NULL;
	struct efi_mokvar_sysfs_attr *mokvar_sysfs = NULL;
	int err = 0;

	if (efi_mokvar_table_size == 0)
		return -ENOENT;

	config_va = memremap(efi.mokvar_table, efi_mokvar_table_size,
			     MEMREMAP_WB);
	if (!config_va) {
		pr_err("Failed to map EFI MOKvar config table\n");
		return -ENOMEM;
	}
	efi_mokvar_table_va = config_va;

	mokvar_kobj = kobject_create_and_add("mok-variables", efi_kobj);
	if (!mokvar_kobj) {
		pr_err("Failed to create EFI mok-variables sysfs entry\n");
		return -ENOMEM;
	}

	while (efi_mokvar_entry_next(&mokvar_entry)) {
		mokvar_sysfs = kzalloc(sizeof(*mokvar_sysfs), GFP_KERNEL);
		if (!mokvar_sysfs) {
			err = -ENOMEM;
			break;
		}

		sysfs_bin_attr_init(&mokvar_sysfs->bin_attr);
		mokvar_sysfs->bin_attr.private = mokvar_entry;
		mokvar_sysfs->bin_attr.attr.name = mokvar_entry->name;
		mokvar_sysfs->bin_attr.attr.mode = 0400;
		mokvar_sysfs->bin_attr.size = mokvar_entry->data_size;
		mokvar_sysfs->bin_attr.read = efi_mokvar_sysfs_read;

		err = sysfs_create_bin_file(mokvar_kobj,
					   &mokvar_sysfs->bin_attr);
		if (err)
			break;

		list_add_tail(&mokvar_sysfs->node, &efi_mokvar_sysfs_list);
	}

	if (err) {
		pr_err("Failed to create some EFI mok-variables sysfs entries\n");
		kfree(mokvar_sysfs);
	}
	return err;
}
device_initcall(efi_mokvar_sysfs_init);
