Am 28. Juli 2026 18:49:48 MESZ schrieb Scott Moser <[email protected]>:
>efi_bootmgr_delete_invalid_boot_option(), eficonfig_show_boot_selection(),
>and eficonfig_create_change_boot_order_entry() each enumerate all EFI
>variables by repeatedly calling efi_next_variable_name() in a loop,
>passing the same efi_guid_t as both input and output. GetNextVariableName()
>needs the vendor GUID returned by the previous call, together with the
>variable name it returned, to know where to resume.
>
>In each of these loops the efi_guid_t was declared inside the loop body,
>so a new instance comes into scope on every iteration. Relying on it to
>still hold the previous iteration's value depends on the compiler reusing
>the same stack slot across iterations, which is undefined behavior. With
>a compiler that zero-initializes locals by default (e.g. clang, or gcc
>configured with -ftrivial-auto-var-init=zero), the GUID is cleared on
>every iteration, so the lookup of the variable name returned by the
>previous call fails and efi_init_obj_list() aborts:
>
>  Cannot initialize UEFI sub-system
>  ** Booting bootflow ... with efi
>  Boot failed (err=-22)
>
>Move the efi_guid_t declarations out of the loops so the value written
>by the previous efi_next_variable_name() call is preserved across
>iterations.
>
>Fixes: 140a8959d48f ("eficonfig: use efi_get_next_variable_name_int()")
>Signed-off-by: Scott Moser <[email protected]>
>---
> cmd/eficonfig.c              | 4 ++--
> lib/efi_loader/efi_bootmgr.c | 2 +-
> 2 files changed, 3 insertions(+), 3 deletions(-)
>
>diff --git a/cmd/eficonfig.c b/cmd/eficonfig.c
>index 4d060e3007c..cd66f05fb7a 100644
>--- a/cmd/eficonfig.c
>+++ b/cmd/eficonfig.c
>@@ -1844,6 +1844,7 @@ static efi_status_t 
>eficonfig_show_boot_selection(unsigned int *selected)
>       struct efimenu *efi_menu;
>       struct list_head *pos, *n;
>       struct eficonfig_entry *entry;
>+      efi_guid_t guid = {};
> 
>       efi_menu = calloc(1, sizeof(struct efimenu));
>       if (!efi_menu)
>@@ -1872,7 +1873,6 @@ static efi_status_t 
>eficonfig_show_boot_selection(unsigned int *selected)
>       var_name16[0] = 0;
>       for (;;) {
>               int index;
>-              efi_guid_t guid;
> 
>               ret = efi_next_variable_name(&buf_size, &var_name16, &guid);
>               if (ret == EFI_NOT_FOUND)
>@@ -2245,6 +2245,7 @@ static efi_status_t 
>eficonfig_create_change_boot_order_entry(struct efimenu *efi
>       u16 *var_name16 = NULL;
>       efi_uintn_t size, buf_size;
>       struct eficonfig_save_boot_order_data *save_data;
>+      efi_guid_t guid = {};

Thank you for addressing this issue.

According to the UEFI specification:

"When VariableName is a pointer to a Null character, VendorGuid is ignored."

Initialization of the GUID is not needed and should be avoided to reduce the 
code size.

> 
>       /* list the load option in the order of BootOrder variable */
>       for (i = 0; i < num; i++) {
>@@ -2265,7 +2266,6 @@ static efi_status_t 
>eficonfig_create_change_boot_order_entry(struct efimenu *efi
>       var_name16[0] = 0;
>       for (;;) {
>               int index;
>-              efi_guid_t guid;
> 
>               if (efi_menu->count >= EFICONFIG_ENTRY_NUM_MAX - 2)
>                       break;
>diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c
>index 8c9a9b5eb56..3ee47000d23 100644
>--- a/lib/efi_loader/efi_bootmgr.c
>+++ b/lib/efi_loader/efi_bootmgr.c
>@@ -934,6 +934,7 @@ static efi_status_t 
>efi_bootmgr_delete_invalid_boot_option(struct eficonfig_medi
>       efi_status_t ret = EFI_SUCCESS;
>       u16 *delete_index_list = NULL, *p;
>       efi_uintn_t buf_size;
>+      efi_guid_t guid = {};

ditto

Best regards

Heinrich


> 
>       buf_size = 128;
>       var_name16 = malloc(buf_size);
>@@ -943,7 +944,6 @@ static efi_status_t 
>efi_bootmgr_delete_invalid_boot_option(struct eficonfig_medi
>       var_name16[0] = 0;
>       for (;;) {
>               int index;
>-              efi_guid_t guid;
>               efi_uintn_t tmp;
> 
>               ret = efi_next_variable_name(&buf_size, &var_name16, &guid);

Reply via email to