| From f45812cc23fb74bef62d4eb8a69fe7218f4b9f2a Mon Sep 17 00:00:00 2001 |
| From: Tim Schumacher <timschumi@gmx.de> |
| Date: Fri, 26 Jan 2024 17:25:23 +0100 |
| Subject: efivarfs: Request at most 512 bytes for variable names |
| |
| From: Tim Schumacher <timschumi@gmx.de> |
| |
| commit f45812cc23fb74bef62d4eb8a69fe7218f4b9f2a upstream. |
| |
| Work around a quirk in a few old (2011-ish) UEFI implementations, where |
| a call to `GetNextVariableName` with a buffer size larger than 512 bytes |
| will always return EFI_INVALID_PARAMETER. |
| |
| There is some lore around EFI variable names being up to 1024 bytes in |
| size, but this has no basis in the UEFI specification, and the upper |
| bounds are typically platform specific, and apply to the entire variable |
| (name plus payload). |
| |
| Given that Linux does not permit creating files with names longer than |
| NAME_MAX (255) bytes, 512 bytes (== 256 UTF-16 characters) is a |
| reasonable limit. |
| |
| Cc: <stable@vger.kernel.org> # 6.1+ |
| Signed-off-by: Tim Schumacher <timschumi@gmx.de> |
| Signed-off-by: Ard Biesheuvel <ardb@kernel.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| fs/efivarfs/vars.c | 17 +++++++++++------ |
| 1 file changed, 11 insertions(+), 6 deletions(-) |
| |
| --- a/fs/efivarfs/vars.c |
| +++ b/fs/efivarfs/vars.c |
| @@ -372,7 +372,7 @@ static void dup_variable_bug(efi_char16_ |
| int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *), |
| void *data, bool duplicates, 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; |
| @@ -389,12 +389,13 @@ int efivar_init(int (*func)(efi_char16_t |
| 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, |
| @@ -431,9 +432,13 @@ int efivar_init(int (*func)(efi_char16_t |
| 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; |
| } |