]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
boot: Try to detect overlapping PE sections 24628/head
authorJan Janssen <medhefgo@web.de>
Sat, 10 Sep 2022 07:02:35 +0000 (09:02 +0200)
committerJan Janssen <medhefgo@web.de>
Sat, 10 Sep 2022 07:02:35 +0000 (09:02 +0200)
This should help finding the cause of boot failures because of badly
assembled unified kernel images.

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

index efe056c225a507b1d5cf8a3011c87e030dd9fe9f..9eefe6571f9b898ccbc52da20218d1d90d1b83af 100644 (file)
@@ -199,9 +199,12 @@ efi_cflags = [
         ]
 )
 
-# On some distros, sd-boot/-stub may trigger some bug somewhere that will cause
-# kernel execution to fail. The cause seems to be purely based on code size and
-# always compiling with at least -O1 will work around that.
+# Our code size has increased enough to possibly create overlapping PE sections
+# at sd-stub runtime, which will often enough prevent the image from booting.
+# This only happens because the usual instructions for assembling a unified
+# kernel image contain hardcoded addresses for section VMAs added in. Until a
+# proper solution is in place, we can at least compile with as least -O1 to
+# reduce the likelyhood of this happening.
 # https://github.com/systemd/systemd/issues/24202
 efi_cflags += '-O1'
 
index 2b260d42122d18c9f0009731615ee6035d9b371b..852198f895fac0b7965fae34db20c22a546e9c54 100644 (file)
@@ -151,9 +151,17 @@ static void locate_sections(
         assert(offsets);
         assert(sizes);
 
+        size_t prev_section_addr = 0;
+
         for (UINTN i = 0; i < n_table; i++) {
                 const PeSectionHeader *sect = section_table + i;
 
+                if (in_memory) {
+                        if (prev_section_addr > sect->VirtualAddress)
+                                log_error_stall(u"Overlapping PE sections detected. Boot may fail due to image memory corruption!");
+                        prev_section_addr = sect->VirtualAddress + sect->VirtualSize;
+                }
+
                 for (UINTN j = 0; sections[j]; j++) {
                         if (memcmp(sect->Name, sections[j], strlen8(sections[j])) != 0)
                                 continue;