Merge pull request #24628 from medhefgo/boot-sections
boot: Try to detect overlapping PE sections
This commit is contained in:
@@ -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'
|
||||
|
||||
|
||||
+17
-11
@@ -142,25 +142,31 @@ static void locate_sections(
|
||||
const PeSectionHeader section_table[],
|
||||
UINTN n_table,
|
||||
const char * const sections[],
|
||||
UINTN *addrs,
|
||||
UINTN *offsets,
|
||||
UINTN *sizes) {
|
||||
UINTN *sizes,
|
||||
bool in_memory) {
|
||||
|
||||
assert(section_table);
|
||||
assert(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;
|
||||
|
||||
if (addrs)
|
||||
addrs[j] = sect->VirtualAddress;
|
||||
if (offsets)
|
||||
offsets[j] = sect->PointerToRawData;
|
||||
offsets[j] = in_memory ? sect->VirtualAddress : sect->PointerToRawData;
|
||||
sizes[j] = sect->VirtualSize;
|
||||
}
|
||||
}
|
||||
@@ -178,8 +184,8 @@ static uint32_t get_compatibility_entry_address(const DosFileHeader *dos, const
|
||||
pe->FileHeader.NumberOfSections,
|
||||
sections,
|
||||
&addr,
|
||||
NULL,
|
||||
&size);
|
||||
&size,
|
||||
/*in_memory=*/true);
|
||||
|
||||
if (size == 0)
|
||||
return 0;
|
||||
@@ -274,8 +280,8 @@ EFI_STATUS pe_memory_locate_sections(const void *base, const char * const sectio
|
||||
pe->FileHeader.NumberOfSections,
|
||||
sections,
|
||||
addrs,
|
||||
NULL,
|
||||
sizes);
|
||||
sizes,
|
||||
/*in_memory=*/true);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
@@ -338,7 +344,7 @@ EFI_STATUS pe_file_locate_sections(
|
||||
return EFI_LOAD_ERROR;
|
||||
|
||||
locate_sections(section_table, pe.FileHeader.NumberOfSections,
|
||||
sections, NULL, offsets, sizes);
|
||||
sections, offsets, sizes, /*in_memory=*/false);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user