Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
fallback: find_boot_option() needs to return the index for the boot e…
…ntry in optnum

The CopyMem() calls in add_to_boot_list() expect that
find_boot_option() returned an index to the matching entry in the
BootOrder array. The previous code returned the numerical portion of
the boot entry label, which in some cases resulted in -1 *
sizeof(CHAR16) being passed to CopyMem() which would in turn corrupt
the running firmware resulting in an exception and a failure to boot
or reset.
  • Loading branch information
jsetje authored and vathpela committed Aug 10, 2021
1 parent 4583db4 commit 1b30c2b
Showing 1 changed file with 9 additions and 4 deletions.
13 changes: 9 additions & 4 deletions fallback.c
Expand Up @@ -462,10 +462,15 @@ find_boot_option(EFI_DEVICE_PATH *dp, EFI_DEVICE_PATH *fulldp,
first_new_option_size = StrLen(arguments) * sizeof (CHAR16);
}

*optnum = xtoi(varname + 4);
FreePool(candidate);
FreePool(data);
return EFI_SUCCESS;
/* find the index for the matching entry in BootOrder */
UINT16 bootnum = xtoi(varname + 4);
for (*optnum = 0; *optnum < nbootorder; (*optnum)++) {
if (bootorder[*optnum] == bootnum) {
FreePool(candidate);
FreePool(data);
return EFI_SUCCESS;
}
}
}
FreePool(candidate);
FreePool(data);
Expand Down

1 comment on commit 1b30c2b

@rmetrich
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This patch fixes an issue on Dell R740 hardware as well when booting with BOOTX64 which then switches to fallback firmware:
depending on the bootorder table size, the original code was crashing the system.

Still this patch brings a new issue: duplicated entries.
Indeed, due to the new loop, it's possible that the Linux entry is not currently found in the BootOrder list, which ends up creating a new Linux entry, as shown in the snippet below (verbose mode in fbx64):

efi_main:1113: System BootOrder not found.  Initializing defaults.
set_boot_order:493: Original nbootorder: 3
Original BootOrder: 0000 0001 0002
 :
add_to_boot_list:585: device path: "HD(1,GPT,99D47E76-590F-48FD-8FD6-0A0CE790D635)/\EFI\redhat\shimx64.efi"
find_boot_option:454: Found boot entry "Boot0006" with label "Red Hat Enterprise Linux" for file "\EFI\redhat\shimx64.efi"
add_boot_option:245: Creating boot entry "Boot0005" with label "Red Hat Enterprise Linux" for file "\EFI\redhat\shimx64.efi"
add_boot_option:282: nbootorder: 4
BootOrder: 0005 0000 0001 0002
find_boot_options:917: Found directory named "Dell"
update_boot_order:516: nbootorder: 4
BootOrder: 0005 0000 0001 0002

Above, we can see the boot entry was found (0006) but not taken into account because it was not in the current bootorder table (the new code searches for this).
Hence a new entry 0005 was created and bootorder modified accordingly.

Please sign in to comment.