Commit 1b10b390 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'efi-next-for-v6.10' of git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi

Pull EFI updates from Ard Biesheuvel:
 "Only a handful of changes this cycle, consisting of cleanup work and a
  low-prio bugfix:

   - Additional cleanup by Tim for the efivarfs variable name length
     confusion

   - Avoid freeing a bogus pointer when virtual remapping is omitted in
     the EFI boot stub"

* tag 'efi-next-for-v6.10' of git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi:
  efi: libstub: only free priv.runtime_map when allocated
  efi: Clear up misconceptions about a maximum variable name size
  efivarfs: Remove unused internal struct members
  Documentation: Mark the 'efivars' sysfs interface as removed
  efi: pstore: Request at most 512 bytes for variable names
parents 614da38e 4b2543f7
What: /sys/firmware/efi/vars
Date: April 2004, removed March 2023
Description:
This directory exposed interfaces for interacting with
EFI variables. For more information on EFI variables,
see 'Variable Services' in the UEFI specification
(section 7.2 in specification version 2.3 Errata D).
The 'efivars' sysfs interface was removed in March of 2023,
after being considered deprecated no later than September
of 2020. Its functionality has been replaced by the
'efivarfs' filesystem.
What: /sys/firmware/efi/vars
Date: April 2004
Contact: Matt Domsch <Matt_Domsch@dell.com>
Description:
This directory exposes interfaces for interactive with
EFI variables. For more information on EFI variables,
see 'Variable Services' in the UEFI specification
(section 7.2 in specification version 2.3 Errata D).
In summary, EFI variables are named, and are classified
into separate namespaces through the use of a vendor
GUID. They also have an arbitrary binary value
associated with them.
The efivars module enumerates these variables and
creates a separate directory for each one found. Each
directory has a name of the form "<key>-<vendor guid>"
and contains the following files:
=============== ========================================
attributes: A read-only text file enumerating the
EFI variable flags. Potential values
include:
EFI_VARIABLE_NON_VOLATILE
EFI_VARIABLE_BOOTSERVICE_ACCESS
EFI_VARIABLE_RUNTIME_ACCESS
EFI_VARIABLE_HARDWARE_ERROR_RECORD
EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
See the EFI documentation for an
explanation of each of these variables.
data: A read-only binary file that can be read
to attain the value of the EFI variable
guid: The vendor GUID of the variable. This
should always match the GUID in the
variable's name.
raw_var: A binary file that can be read to obtain
a structure that contains everything
there is to know about the variable.
For structure definition see "struct
efi_variable" in the kernel sources.
This file can also be written to in
order to update the value of a variable.
For this to work however, all fields of
the "struct efi_variable" passed must
match byte for byte with the structure
read out of the file, save for the value
portion.
**Note** the efi_variable structure
read/written with this file contains a
'long' type that may change widths
depending on your underlying
architecture.
size: As ASCII representation of the size of
the variable's value.
=============== ========================================
In addition, two other magic binary files are provided
in the top-level directory and are used for adding and
removing variables:
=============== ========================================
new_var: Takes a "struct efi_variable" and
instructs the EFI firmware to create a
new variable.
del_var: Takes a "struct efi_variable" and
instructs the EFI firmware to remove any
variable that has a matching vendor GUID
and variable key name.
=============== ========================================
...@@ -40,4 +40,4 @@ accidentally. ...@@ -40,4 +40,4 @@ accidentally.
*See also:* *See also:*
- Documentation/admin-guide/acpi/ssdt-overlays.rst - Documentation/admin-guide/acpi/ssdt-overlays.rst
- Documentation/ABI/stable/sysfs-firmware-efi-vars - Documentation/ABI/removed/sysfs-firmware-efi-vars
...@@ -162,7 +162,15 @@ static ssize_t efi_pstore_read(struct pstore_record *record) ...@@ -162,7 +162,15 @@ static ssize_t efi_pstore_read(struct pstore_record *record)
efi_status_t status; efi_status_t status;
for (;;) { for (;;) {
varname_size = 1024; /*
* A small set of old UEFI implementations reject sizes
* above a certain threshold, the lowest seen in the wild
* is 512.
*
* TODO: Commonize with the iteration implementation in
* fs/efivarfs to keep all the quirks in one place.
*/
varname_size = 512;
/* /*
* If this is the first read() call in the pstore enumeration, * If this is the first read() call in the pstore enumeration,
......
...@@ -335,7 +335,7 @@ efi_status_t allocate_new_fdt_and_exit_boot(void *handle, ...@@ -335,7 +335,7 @@ efi_status_t allocate_new_fdt_and_exit_boot(void *handle,
fail: fail:
efi_free(fdt_size, fdt_addr); efi_free(fdt_size, fdt_addr);
if (!efi_novamap)
efi_bs_call(free_pool, priv.runtime_map); efi_bs_call(free_pool, priv.runtime_map);
return EFI_LOAD_ERROR; return EFI_LOAD_ERROR;
......
...@@ -215,7 +215,7 @@ efi_status_t efivar_set_variable_locked(efi_char16_t *name, efi_guid_t *vendor, ...@@ -215,7 +215,7 @@ efi_status_t efivar_set_variable_locked(efi_char16_t *name, efi_guid_t *vendor,
if (data_size > 0) { if (data_size > 0) {
status = check_var_size(nonblocking, attr, status = check_var_size(nonblocking, attr,
data_size + ucs2_strsize(name, 1024)); data_size + ucs2_strsize(name, EFI_VAR_NAME_LEN));
if (status != EFI_SUCCESS) if (status != EFI_SUCCESS)
return status; return status;
} }
......
...@@ -24,11 +24,8 @@ struct efivarfs_fs_info { ...@@ -24,11 +24,8 @@ struct efivarfs_fs_info {
struct efi_variable { struct efi_variable {
efi_char16_t VariableName[EFI_VAR_NAME_LEN/sizeof(efi_char16_t)]; efi_char16_t VariableName[EFI_VAR_NAME_LEN/sizeof(efi_char16_t)];
efi_guid_t VendorGuid; efi_guid_t VendorGuid;
unsigned long DataSize;
__u8 Data[1024];
efi_status_t Status;
__u32 Attributes; __u32 Attributes;
} __attribute__((packed)); };
struct efivar_entry { struct efivar_entry {
struct efi_variable var; struct efi_variable var;
......
...@@ -295,9 +295,9 @@ static bool variable_is_present(efi_char16_t *variable_name, efi_guid_t *vendor, ...@@ -295,9 +295,9 @@ static bool variable_is_present(efi_char16_t *variable_name, efi_guid_t *vendor,
unsigned long strsize1, strsize2; unsigned long strsize1, strsize2;
bool found = false; bool found = false;
strsize1 = ucs2_strsize(variable_name, 1024); strsize1 = ucs2_strsize(variable_name, EFI_VAR_NAME_LEN);
list_for_each_entry_safe(entry, n, head, list) { list_for_each_entry_safe(entry, n, head, list) {
strsize2 = ucs2_strsize(entry->var.VariableName, 1024); strsize2 = ucs2_strsize(entry->var.VariableName, EFI_VAR_NAME_LEN);
if (strsize1 == strsize2 && if (strsize1 == strsize2 &&
!memcmp(variable_name, &(entry->var.VariableName), !memcmp(variable_name, &(entry->var.VariableName),
strsize2) && strsize2) &&
...@@ -396,6 +396,7 @@ int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *, ...@@ -396,6 +396,7 @@ int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *,
do { do {
variable_name_size = 512; variable_name_size = 512;
BUILD_BUG_ON(EFI_VAR_NAME_LEN < 512);
status = efivar_get_next_variable(&variable_name_size, status = efivar_get_next_variable(&variable_name_size,
variable_name, variable_name,
......
...@@ -1072,12 +1072,11 @@ static inline u64 efivar_reserved_space(void) { return 0; } ...@@ -1072,12 +1072,11 @@ static inline u64 efivar_reserved_space(void) { return 0; }
#endif #endif
/* /*
* The maximum size of VariableName + Data = 1024 * There is no actual upper limit specified for the variable name size.
* Therefore, it's reasonable to save that much *
* space in each part of the structure, * This limit exists only for practical purposes, since name conversions
* and we use a page for reading/writing. * are bounds-checked and name data is occasionally stored in-line.
*/ */
#define EFI_VAR_NAME_LEN 1024 #define EFI_VAR_NAME_LEN 1024
int efivars_register(struct efivars *efivars, int efivars_register(struct efivars *efivars,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment