]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-boot: Try harder to detect ourselves
authorJan Janssen <medhefgo@web.de>
Fri, 13 Aug 2021 17:03:35 +0000 (19:03 +0200)
committerJan Janssen <medhefgo@web.de>
Mon, 16 Aug 2021 08:49:18 +0000 (10:49 +0200)
By moving our magic string into its own PE section, we can forego
grepping for it.

src/boot/efi/boot.c
src/boot/efi/meson.build

index 9a81af42ac6e9cafb3db21fac89ca4fb176f8c62..70f5a2ba52c0e009b1d3f594c4fbec5c50935627 100644 (file)
@@ -22,7 +22,7 @@
 #endif
 
 /* magic string to find in the binary image */
-static const char __attribute__((used)) magic[] = "#### LoaderInfo: systemd-boot " GIT_VERSION " ####";
+static const char _used_ _section_(".sdmagic") magic[] = "#### LoaderInfo: systemd-boot " GIT_VERSION " ####";
 
 enum loader_type {
         LOADER_UNDEFINED,
@@ -1792,6 +1792,29 @@ static ConfigEntry *config_entry_add_loader(
         return entry;
 }
 
+static BOOLEAN is_sd_boot(EFI_FILE *root_dir, const CHAR16 *loader_path) {
+        EFI_STATUS err;
+        const CHAR8 *sections[] = {
+                (CHAR8 *)".sdmagic",
+                NULL
+        };
+        UINTN offset = 0, size = 0, read;
+        _cleanup_freepool_ CHAR8 *content = NULL;
+
+        assert(root_dir);
+        assert(loader_path);
+
+        err = pe_file_locate_sections(root_dir, loader_path, sections, &offset, &size);
+        if (EFI_ERROR(err) || size != sizeof(magic))
+                return FALSE;
+
+        err = file_read(root_dir, loader_path, offset, size, &content, &read);
+        if (EFI_ERROR(err) || size != read)
+                return FALSE;
+
+        return CompareMem(content, magic, sizeof(magic)) == 0;
+}
+
 static BOOLEAN config_entry_add_loader_auto(
                 Config *config,
                 EFI_HANDLE *device,
@@ -1811,25 +1834,23 @@ static BOOLEAN config_entry_add_loader_auto(
         assert(root_dir);
         assert(id);
         assert(title);
-        assert(loader);
+        assert(loader || loaded_image_path);
 
         if (!config->auto_entries)
                 return FALSE;
 
-        /* do not add an entry for ourselves */
         if (loaded_image_path) {
-                UINTN len;
-                _cleanup_freepool_ CHAR8 *content = NULL;
-
-                if (StriCmp(loader, loaded_image_path) == 0)
+                loader = L"\\EFI\\BOOT\\BOOT" EFI_MACHINE_TYPE_NAME ".efi";
+
+                /* We are trying to add the default EFI loader here,
+                 * but we do not want to do that if that would be us.
+                 *
+                 * If the default loader is not us, it might be shim. It would
+                 * chainload GRUBX64.EFI in that case, which might be us.*/
+                if (StriCmp(loader, loaded_image_path) == 0 ||
+                    is_sd_boot(root_dir, loader) ||
+                    is_sd_boot(root_dir, L"\\EFI\\BOOT\\GRUB" EFI_MACHINE_TYPE_NAME L".EFI"))
                         return FALSE;
-
-                /* look for systemd-boot magic string */
-                err = file_read(root_dir, loader, 0, 100*1024, &content, &len);
-                if (!EFI_ERROR(err))
-                        for (CHAR8 *start = content; start <= content + len - sizeof(magic) - 1; start++)
-                                if (start[0] == magic[0] && CompareMem(start, magic, sizeof(magic) - 1) == 0)
-                                        return FALSE;
         }
 
         /* check existence */
@@ -2414,7 +2435,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
         config_entry_add_loader_auto(&config, loaded_image->DeviceHandle, root_dir, NULL,
                                      L"auto-efi-shell", 's', L"EFI Shell", L"\\shell" EFI_MACHINE_TYPE_NAME ".efi");
         config_entry_add_loader_auto(&config, loaded_image->DeviceHandle, root_dir, loaded_image_path,
-                                     L"auto-efi-default", '\0', L"EFI Default Loader", L"\\EFI\\Boot\\boot" EFI_MACHINE_TYPE_NAME ".efi");
+                                     L"auto-efi-default", '\0', L"EFI Default Loader", NULL);
         config_entry_add_osx(&config);
 
         if (config.auto_firmware && efivar_get_uint64_le(EFI_GLOBAL_GUID, L"OsIndicationsSupported", &osind) == EFI_SUCCESS) {
index c96a16426a477a6a6b097690d65c031cbe03780b..3d16ce84b5bf275b6c39416e767ef22b158626fe 100644 (file)
@@ -292,6 +292,7 @@ if have_gnu_efi
                                    '-j', '.text',
                                    '-j', '.sdata',
                                    '-j', '.sbat',
+                                   '-j', '.sdmagic',
                                    '-j', '.data',
                                    '-j', '.dynamic',
                                    '-j', '.dynsym',