| From 258dd902022cb10c83671176688074879517fd21 Mon Sep 17 00:00:00 2001 |
| From: Jann Horn <jannh@google.com> |
| Date: Fri, 18 Feb 2022 19:05:59 +0100 |
| Subject: efivars: Respect "block" flag in efivar_entry_set_safe() |
| |
| From: Jann Horn <jannh@google.com> |
| |
| commit 258dd902022cb10c83671176688074879517fd21 upstream. |
| |
| When the "block" flag is false, the old code would sometimes still call |
| check_var_size(), which wrongly tells ->query_variable_store() that it can |
| block. |
| |
| As far as I can tell, this can't really materialize as a bug at the moment, |
| because ->query_variable_store only does something on X86 with generic EFI, |
| and in that configuration we always take the efivar_entry_set_nonblocking() |
| path. |
| |
| Fixes: ca0e30dcaa53 ("efi: Add nonblocking option to efi_query_variable_store()") |
| Signed-off-by: Jann Horn <jannh@google.com> |
| Signed-off-by: Ard Biesheuvel <ardb@kernel.org> |
| Link: https://lore.kernel.org/r/20220218180559.1432559-1-jannh@google.com |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/firmware/efi/vars.c | 5 ++++- |
| 1 file changed, 4 insertions(+), 1 deletion(-) |
| |
| --- a/drivers/firmware/efi/vars.c |
| +++ b/drivers/firmware/efi/vars.c |
| @@ -750,6 +750,7 @@ int efivar_entry_set_safe(efi_char16_t * |
| { |
| const struct efivar_operations *ops; |
| efi_status_t status; |
| + unsigned long varsize; |
| |
| if (!__efivars) |
| return -EINVAL; |
| @@ -772,15 +773,17 @@ int efivar_entry_set_safe(efi_char16_t * |
| return efivar_entry_set_nonblocking(name, vendor, attributes, |
| size, data); |
| |
| + varsize = size + ucs2_strsize(name, 1024); |
| if (!block) { |
| if (down_trylock(&efivars_lock)) |
| return -EBUSY; |
| + status = check_var_size_nonblocking(attributes, varsize); |
| } else { |
| if (down_interruptible(&efivars_lock)) |
| return -EINTR; |
| + status = check_var_size(attributes, varsize); |
| } |
| |
| - status = check_var_size(attributes, size + ucs2_strsize(name, 1024)); |
| if (status != EFI_SUCCESS) { |
| up(&efivars_lock); |
| return -ENOSPC; |