]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[efi] Allow currently selected image to be opened as "grub*.efi"
authorMichael Brown <mcb30@ipxe.org>
Fri, 5 May 2023 11:51:09 +0000 (12:51 +0100)
committerMichael Brown <mcb30@ipxe.org>
Fri, 5 May 2023 13:54:20 +0000 (14:54 +0100)
Versions 15.4 and earlier of the UEFI shim are incapable of correctly
parsing the command line in order to extract the second stage loader
filename, and will always attempt to load "grubx64.efi" or equivalent.

Versions 15.3 and later of the UEFI shim are currently incapable of
loading a Linux kernel directly anyway, since the kernel does not
include SBAT metadata.  These versions will require a genuine
shim-signed GRUB binary to be used as a crutch to assist shim in
loading a Linux kernel.

This leaves versions 15.2 and earlier of the UEFI shim (as currently
used in e.g. RHEL7) as being capable of directly loading a Linux
kernel, but incorrectly attempting to load it using the filename
"grubx64.efi" or equivalent.  To support the bugs in these older
versions of the UEFI shim, allow the currently selected image to be
opened via any filename of the form "grub*.efi".

Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/interface/efi/efi_file.c

index 673f902d58414ab30e87e3a45ad73368a0536164..266de4a6c1db5d825b859e8e2ebd8aac8b3714ff 100644 (file)
@@ -374,6 +374,7 @@ efi_file_open ( EFI_FILE_PROTOCOL *this, EFI_FILE_PROTOCOL **new,
        char buf[ wcslen ( wname ) + 1 /* NUL */ ];
        struct image *image;
        char *name;
+       char *sep;
 
        /* Convert name to ASCII */
        snprintf ( buf, sizeof ( buf ), "%ls", wname );
@@ -413,6 +414,16 @@ efi_file_open ( EFI_FILE_PROTOCOL *this, EFI_FILE_PROTOCOL **new,
                                             new );
        }
 
+       /* Allow currently selected image to be opened as "grub*.efi",
+        * to work around buggy versions of the UEFI shim.
+        */
+       if ( ( strncasecmp ( name, "grub", 4 ) == 0 ) &&
+            ( ( sep = strrchr ( name, '.' ) ) != NULL ) &&
+            ( strcasecmp ( sep, ".efi" ) == 0 ) &&
+            ( ( image = image_find_selected() ) != NULL ) ) {
+               return efi_file_open_image ( image, wname, new );
+       }
+
        DBGC ( file, "EFIFILE %ls does not exist\n", wname );
        return EFI_NOT_FOUND;
 }