2
0
mirror of https://github.com/edk2-porting/linux-next.git synced 2024-11-15 06:05:13 +08:00

EFI fixes for v6.8 #2

- Fix phys_addr_t size confusion in 32-bit capsule loader
 - Reduce maximum EFI variable name size to 512 to work around buggy
   firmware
 - Drop some redundant code from efivarfs while at it
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYIAB0WIQQQm/3uucuRGn1Dmh0wbglWLn0tXAUCZdr/HgAKCRAwbglWLn0t
 XGqrAP96SmiLbkEBzBAkjpIvQIwoiPUAQmfBXs4PuZ6MH/aq3wEA0VOxxH8CpVAu
 dpjd2HIjO59zMr4G7BvR/ezit3Gp2A0=
 =Bd3Z
 -----END PGP SIGNATURE-----

Merge tag 'efi-fixes-for-v6.8-2' of git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi

Pull EFI fixes from Ard Biesheuvel:
 "Only the EFI variable name size change is significant, and will be
  backported once it lands. The others are cleanup.

   - Fix phys_addr_t size confusion in 32-bit capsule loader

   - Reduce maximum EFI variable name size to 512 to work around buggy
     firmware

   - Drop some redundant code from efivarfs while at it"

* tag 'efi-fixes-for-v6.8-2' of git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi:
  efivarfs: Drop 'duplicates' bool parameter on efivar_init()
  efivarfs: Drop redundant cleanup on fill_super() failure
  efivarfs: Request at most 512 bytes for variable names
  efi/capsule-loader: fix incorrect allocation size
This commit is contained in:
Linus Torvalds 2024-03-01 11:40:29 -08:00
commit 2bbb54ba1b
4 changed files with 16 additions and 18 deletions

View File

@ -292,7 +292,7 @@ static int efi_capsule_open(struct inode *inode, struct file *file)
return -ENOMEM;
}
cap_info->phys = kzalloc(sizeof(void *), GFP_KERNEL);
cap_info->phys = kzalloc(sizeof(phys_addr_t), GFP_KERNEL);
if (!cap_info->phys) {
kfree(cap_info->pages);
kfree(cap_info);

View File

@ -38,7 +38,7 @@ struct efivar_entry {
int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *,
struct list_head *),
void *data, bool duplicates, struct list_head *head);
void *data, struct list_head *head);
int efivar_entry_add(struct efivar_entry *entry, struct list_head *head);
void __efivar_entry_add(struct efivar_entry *entry, struct list_head *head);

View File

@ -343,12 +343,7 @@ static int efivarfs_fill_super(struct super_block *sb, struct fs_context *fc)
if (err)
return err;
err = efivar_init(efivarfs_callback, (void *)sb, true,
&sfi->efivarfs_list);
if (err)
efivar_entry_iter(efivarfs_destroy, &sfi->efivarfs_list, NULL);
return err;
return efivar_init(efivarfs_callback, sb, &sfi->efivarfs_list);
}
static int efivarfs_get_tree(struct fs_context *fc)

View File

@ -361,7 +361,6 @@ static void dup_variable_bug(efi_char16_t *str16, efi_guid_t *vendor_guid,
* efivar_init - build the initial list of EFI variables
* @func: callback function to invoke for every variable
* @data: function-specific data to pass to @func
* @duplicates: error if we encounter duplicates on @head?
* @head: initialised head of variable list
*
* Get every EFI variable from the firmware and invoke @func. @func
@ -371,9 +370,9 @@ static void dup_variable_bug(efi_char16_t *str16, efi_guid_t *vendor_guid,
*/
int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *,
struct list_head *),
void *data, bool duplicates, struct list_head *head)
void *data, struct list_head *head)
{
unsigned long variable_name_size = 1024;
unsigned long variable_name_size = 512;
efi_char16_t *variable_name;
efi_status_t status;
efi_guid_t vendor_guid;
@ -390,12 +389,13 @@ int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *,
goto free;
/*
* Per EFI spec, the maximum storage allocated for both
* the variable name and variable data is 1024 bytes.
* A small set of old UEFI implementations reject sizes
* above a certain threshold, the lowest seen in the wild
* is 512.
*/
do {
variable_name_size = 1024;
variable_name_size = 512;
status = efivar_get_next_variable(&variable_name_size,
variable_name,
@ -413,8 +413,7 @@ int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *,
* we'll ever see a different variable name,
* and may end up looping here forever.
*/
if (duplicates &&
variable_is_present(variable_name, &vendor_guid,
if (variable_is_present(variable_name, &vendor_guid,
head)) {
dup_variable_bug(variable_name, &vendor_guid,
variable_name_size);
@ -432,9 +431,13 @@ int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *,
break;
case EFI_NOT_FOUND:
break;
case EFI_BUFFER_TOO_SMALL:
pr_warn("efivars: Variable name size exceeds maximum (%lu > 512)\n",
variable_name_size);
status = EFI_NOT_FOUND;
break;
default:
printk(KERN_WARNING "efivars: get_next_variable: status=%lx\n",
status);
pr_warn("efivars: get_next_variable: status=%lx\n", status);
status = EFI_NOT_FOUND;
break;
}