Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * mokvar-table.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (c) 2020 Red Hat
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * Author: Lenny Szubowicz <lszubowi@redhat.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * This module contains the kernel support for the Linux EFI Machine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * Owner Key (MOK) variable configuration table, which is identified by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  * the LINUX_EFI_MOK_VARIABLE_TABLE_GUID.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  * This EFI configuration table provides a more robust alternative to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  * EFI volatile variables by which an EFI boot loader can pass the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  * contents of the Machine Owner Key (MOK) certificate stores to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  * kernel during boot. If both the EFI MOK config table and corresponding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  * EFI MOK variables are present, the table should be considered as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  * more authoritative.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  * This module includes code that validates and maps the EFI MOK table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  * if it's presence was detected very early in boot.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  * Kernel interface routines are provided to walk through all the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  * entries in the MOK config table or to search for a specific named
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  * entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  * The contents of the individual named MOK config table entries are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)  * made available to user space via read-only sysfs binary files under:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  * /sys/firmware/efi/mok-variables/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #define pr_fmt(fmt) "mokvar: " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #include <linux/capability.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #include <linux/efi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #include <linux/kobject.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) #include <asm/early_ioremap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46)  * The LINUX_EFI_MOK_VARIABLE_TABLE_GUID config table is a packed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47)  * sequence of struct efi_mokvar_table_entry, one for each named
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48)  * MOK variable. The sequence is terminated by an entry with a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49)  * completely NULL name and 0 data size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51)  * efi_mokvar_table_size is set to the computed size of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52)  * MOK config table by efi_mokvar_table_init(). This will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53)  * non-zero if and only if the table if present and has been
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54)  * validated by efi_mokvar_table_init().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) static size_t efi_mokvar_table_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59)  * efi_mokvar_table_va is the kernel virtual address at which the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60)  * EFI MOK config table has been mapped by efi_mokvar_sysfs_init().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) static struct efi_mokvar_table_entry *efi_mokvar_table_va;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65)  * Each /sys/firmware/efi/mok-variables/ sysfs file is represented by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66)  * an instance of struct efi_mokvar_sysfs_attr on efi_mokvar_sysfs_list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67)  * bin_attr.private points to the associated EFI MOK config table entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69)  * This list is created during boot and then remains unchanged.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70)  * So no synchronization is currently required to walk the list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) struct efi_mokvar_sysfs_attr {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	struct bin_attribute bin_attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	struct list_head node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) static LIST_HEAD(efi_mokvar_sysfs_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) static struct kobject *mokvar_kobj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81)  * efi_mokvar_table_init() - Early boot validation of EFI MOK config table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83)  * If present, validate and compute the size of the EFI MOK variable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84)  * configuration table. This table may be provided by an EFI boot loader
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85)  * as an alternative to ordinary EFI variables, due to platform-dependent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86)  * limitations. The memory occupied by this table is marked as reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88)  * This routine must be called before efi_free_boot_services() in order
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89)  * to guarantee that it can mark the table as reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91)  * Implicit inputs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92)  * efi.mokvar_table:	Physical address of EFI MOK variable config table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93)  *			or special value that indicates no such table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95)  * Implicit outputs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96)  * efi_mokvar_table_size: Computed size of EFI MOK variable config table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97)  *			The table is considered present and valid if this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98)  *			is non-zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) void __init efi_mokvar_table_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	efi_memory_desc_t md;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	void *va = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	unsigned long cur_offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	unsigned long offset_limit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	unsigned long map_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	unsigned long map_size_needed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	unsigned long size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	struct efi_mokvar_table_entry *mokvar_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	if (!efi_enabled(EFI_MEMMAP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	if (efi.mokvar_table == EFI_INVALID_TABLE_ADDR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	 * The EFI MOK config table must fit within a single EFI memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	 * descriptor range.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	err = efi_mem_desc_lookup(efi.mokvar_table, &md);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 		pr_warn("EFI MOKvar config table is not within the EFI memory map\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	offset_limit = efi_mem_desc_end(&md) - efi.mokvar_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	 * Validate the MOK config table. Since there is no table header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	 * from which we could get the total size of the MOK config table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	 * we compute the total size as we validate each variably sized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	 * entry, remapping as necessary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	while (cur_offset + sizeof(*mokvar_entry) <= offset_limit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 		mokvar_entry = va + cur_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 		map_size_needed = cur_offset + sizeof(*mokvar_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 		if (map_size_needed > map_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 			if (va)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 				early_memunmap(va, map_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 			 * Map a little more than the fixed size entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 			 * header, anticipating some data. It's safe to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 			 * do so as long as we stay within current memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 			 * descriptor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 			map_size = min(map_size_needed + 2*EFI_PAGE_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 				       offset_limit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 			va = early_memremap(efi.mokvar_table, map_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 			if (!va) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 				pr_err("Failed to map EFI MOKvar config table pa=0x%lx, size=%lu.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 				       efi.mokvar_table, map_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 				return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 			mokvar_entry = va + cur_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 		/* Check for last sentinel entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 		if (mokvar_entry->name[0] == '\0') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 			if (mokvar_entry->data_size != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 			err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 		/* Sanity check that the name is null terminated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 		size = strnlen(mokvar_entry->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 			       sizeof(mokvar_entry->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 		if (size >= sizeof(mokvar_entry->name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 		/* Advance to the next entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 		cur_offset = map_size_needed + mokvar_entry->data_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	if (va)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 		early_memunmap(va, map_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 		pr_err("EFI MOKvar config table is not valid\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	if (md.type == EFI_BOOT_SERVICES_DATA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 		efi_mem_reserve(efi.mokvar_table, map_size_needed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	efi_mokvar_table_size = map_size_needed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)  * efi_mokvar_entry_next() - Get next entry in the EFI MOK config table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)  * mokvar_entry:	Pointer to current EFI MOK config table entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)  *			or null. Null indicates get first entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)  *			Passed by reference. This is updated to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)  *			same value as the return value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)  * Returns:		Pointer to next EFI MOK config table entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)  *			or null, if there are no more entries.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)  *			Same value is returned in the mokvar_entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)  *			parameter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)  * This routine depends on the EFI MOK config table being entirely
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)  * mapped with it's starting virtual address in efi_mokvar_table_va.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) struct efi_mokvar_table_entry *efi_mokvar_entry_next(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 			struct efi_mokvar_table_entry **mokvar_entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	struct efi_mokvar_table_entry *mokvar_cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	struct efi_mokvar_table_entry *mokvar_next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	size_t size_cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	mokvar_cur = *mokvar_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	*mokvar_entry = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	if (efi_mokvar_table_va == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	if (mokvar_cur == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 		mokvar_next = efi_mokvar_table_va;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 		if (mokvar_cur->name[0] == '\0')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 			return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 		size_cur = sizeof(*mokvar_cur) + mokvar_cur->data_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 		mokvar_next = (void *)mokvar_cur + size_cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	if (mokvar_next->name[0] == '\0')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	*mokvar_entry = mokvar_next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	return mokvar_next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)  * efi_mokvar_entry_find() - Find EFI MOK config entry by name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)  * name:	Name of the entry to look for.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)  * Returns:	Pointer to EFI MOK config table entry if found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)  *		null otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)  * This routine depends on the EFI MOK config table being entirely
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)  * mapped with it's starting virtual address in efi_mokvar_table_va.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) struct efi_mokvar_table_entry *efi_mokvar_entry_find(const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	struct efi_mokvar_table_entry *mokvar_entry = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	while (efi_mokvar_entry_next(&mokvar_entry)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 		if (!strncmp(name, mokvar_entry->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 			     sizeof(mokvar_entry->name)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 			return mokvar_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)  * efi_mokvar_sysfs_read() - sysfs binary file read routine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)  * Returns:	Count of bytes read.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)  * Copy EFI MOK config table entry data for this mokvar sysfs binary file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)  * to the supplied buffer, starting at the specified offset into mokvar table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)  * entry data, for the specified count bytes. The copy is limited by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)  * amount of data in this mokvar config table entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) static ssize_t efi_mokvar_sysfs_read(struct file *file, struct kobject *kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 				 struct bin_attribute *bin_attr, char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 				 loff_t off, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	struct efi_mokvar_table_entry *mokvar_entry = bin_attr->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	if (!capable(CAP_SYS_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	if (off >= mokvar_entry->data_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	if (count >  mokvar_entry->data_size - off)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 		count = mokvar_entry->data_size - off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	memcpy(buf, mokvar_entry->data + off, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)  * efi_mokvar_sysfs_init() - Map EFI MOK config table and create sysfs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)  * Map the EFI MOK variable config table for run-time use by the kernel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)  * and create the sysfs entries in /sys/firmware/efi/mok-variables/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)  * This routine just returns if a valid EFI MOK variable config table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)  * was not found earlier during boot.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)  * This routine must be called during a "middle" initcall phase, i.e.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)  * after efi_mokvar_table_init() but before UEFI certs are loaded
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)  * during late init.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)  * Implicit inputs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)  * efi.mokvar_table:	Physical address of EFI MOK variable config table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)  *			or special value that indicates no such table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)  * efi_mokvar_table_size: Computed size of EFI MOK variable config table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)  *			The table is considered present and valid if this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)  *			is non-zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)  * Implicit outputs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)  * efi_mokvar_table_va:	Start virtual address of the EFI MOK config table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) static int __init efi_mokvar_sysfs_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	void *config_va;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	struct efi_mokvar_table_entry *mokvar_entry = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	struct efi_mokvar_sysfs_attr *mokvar_sysfs = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	if (efi_mokvar_table_size == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 		return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	config_va = memremap(efi.mokvar_table, efi_mokvar_table_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 			     MEMREMAP_WB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	if (!config_va) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 		pr_err("Failed to map EFI MOKvar config table\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	efi_mokvar_table_va = config_va;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	mokvar_kobj = kobject_create_and_add("mok-variables", efi_kobj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	if (!mokvar_kobj) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 		pr_err("Failed to create EFI mok-variables sysfs entry\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	while (efi_mokvar_entry_next(&mokvar_entry)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 		mokvar_sysfs = kzalloc(sizeof(*mokvar_sysfs), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 		if (!mokvar_sysfs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 			err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 		sysfs_bin_attr_init(&mokvar_sysfs->bin_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 		mokvar_sysfs->bin_attr.private = mokvar_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 		mokvar_sysfs->bin_attr.attr.name = mokvar_entry->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 		mokvar_sysfs->bin_attr.attr.mode = 0400;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 		mokvar_sysfs->bin_attr.size = mokvar_entry->data_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 		mokvar_sysfs->bin_attr.read = efi_mokvar_sysfs_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 		err = sysfs_create_bin_file(mokvar_kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 					   &mokvar_sysfs->bin_attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 		list_add_tail(&mokvar_sysfs->node, &efi_mokvar_sysfs_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 		pr_err("Failed to create some EFI mok-variables sysfs entries\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 		kfree(mokvar_sysfs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) device_initcall(efi_mokvar_sysfs_init);