From 00da8d65a3baea8c3745367bea99b1d76f8f129c Mon Sep 17 00:00:00 2001 From: Ilias Apalodimas Date: Thu, 18 Apr 2024 15:54:52 +0300 Subject: efi_loader: add an EFI variable with the file contents Previous patches enabled SetVariableRT using a RAM backend. Although EBBR [0] defines a variable format we can teach userspace tools and write the altered variables, it's better if we skip the ABI requirements completely. So let's add a new variable, in its own namespace called "VarToFile" which contains a binary dump of the updated RT, BS and, NV variables and will be updated when GetVariable is called. Some adjustments are needed to do that. Currently we discard BS-only variables in EBS(). We need to preserve those on the RAM backend that exposes the variables. Since BS-only variables can't appear at runtime we need to move the memory masking checks from efi_var_collect() to efi_get_next_variable_name_mem()/ efi_get_variable_mem() and do the filtering at runtime. We also need an efi_var_collect() variant available at runtime, in order to construct the "VarToFile" buffer on the fly. All users and applications (for linux) have to do when updating a variable is dd that variable in the file described by "RTStorageVolatile". Linux efivarfs uses a first 4 bytes of the output to represent attributes in little-endian format. So, storing variables works like this: $~ efibootmgr -n 0001 $~ dd if=/sys/firmware/efi/efivars/VarToFile-b2ac5fc9-92b7-4acd-aeac-11e818c3130c of=/boot/efi/ubootefi.var skip=4 bs=1 [0] https://arm-software.github.io/ebbr/index.html#document-chapter5-variable-storage Suggested-by: Ard Biesheuvel # dumping all variables to a variable Co-developed-by: Heinrich Schuchardt # contributed on efi_var_collect_mem() Signed-off-by: Heinrich Schuchardt Signed-off-by: Ilias Apalodimas --- include/efi_variable.h | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'include/efi_variable.h') diff --git a/include/efi_variable.h b/include/efi_variable.h index 42a2b7c52be..223bb9a4a5b 100644 --- a/include/efi_variable.h +++ b/include/efi_variable.h @@ -271,13 +271,16 @@ const efi_guid_t *efi_auth_var_get_guid(const u16 *name); * * @variable_name_size: size of variable_name buffer in bytes * @variable_name: name of uefi variable's name in u16 + * @mask: bitmask with required attributes of variables to be collected. + * variables are only collected if all of the required + * attributes match. Use 0 to skip matching * @vendor: vendor's guid * * Return: status code */ efi_status_t __efi_runtime efi_get_next_variable_name_mem(efi_uintn_t *variable_name_size, u16 *variable_name, - efi_guid_t *vendor); + efi_guid_t *vendor, u32 mask); /** * efi_get_variable_mem() - Runtime common code across efi variable * implementations for GetVariable() from @@ -289,12 +292,15 @@ efi_get_next_variable_name_mem(efi_uintn_t *variable_name_size, u16 *variable_na * @data_size: size of the buffer to which the variable value is copied * @data: buffer to which the variable value is copied * @timep: authentication time (seconds since start of epoch) + * @mask: bitmask with required attributes of variables to be collected. + * variables are only collected if all of the required + * attributes match. Use 0 to skip matching * Return: status code */ efi_status_t __efi_runtime efi_get_variable_mem(const u16 *variable_name, const efi_guid_t *vendor, u32 *attributes, efi_uintn_t *data_size, void *data, - u64 *timep); + u64 *timep, u32 mask); /** * efi_get_variable_runtime() - runtime implementation of GetVariable() @@ -334,4 +340,10 @@ efi_get_next_variable_name_runtime(efi_uintn_t *variable_name_size, */ void efi_var_buf_update(struct efi_var_file *var_buf); +efi_status_t __efi_runtime efi_var_collect_mem(struct efi_var_file *buf, + efi_uintn_t *lenp, + u32 check_attr_mask); + +u32 efi_var_entry_len(struct efi_var_entry *var); + #endif -- cgit v1.2.3