boot: handle empty initrd files (#40040)

Commit f8fa4222c9 added extra logic to
account for the size of the initrds before allocating the required memory pages,
but missed checking if the initrds were empty before allocating memory.

Extend the initrd options only when the initrd is valid, and add extra
check for validating that there is at least one valid initrd file before
allocating memory, fixing the following crash when booting with empty
initrd files:

src/boot/log.c:30@efi_assert: systemd-boot: Assertion
 'BS->AllocatePages(type, memory_type, n_pages, &addr) == EFI_SUCCESS'
failed at /usr/src/debug/systemd-boot/257.8/src/boot/util.h:95@xmalloc_pages, halting.

Fixes: f8fa4222c9
("boot: Make initrd_prepare() semantically equivalent to combine_initrds()")
This commit is contained in:
Ricardo Salveti
2025-12-10 04:55:57 +09:00
committed by GitHub
parent ac752f1eff
commit a40f4ba1a8
+17 -6
View File
@@ -2443,12 +2443,6 @@ static EFI_STATUS initrd_prepare(
size_t size = 0, padded_size = 0;
STRV_FOREACH(i, entry->initrd) {
_cleanup_free_ char16_t *o = options;
if (o)
options = xasprintf("%ls initrd=%ls", o, *i);
else
options = xasprintf("initrd=%ls", *i);
_cleanup_file_close_ EFI_FILE *handle = NULL;
err = root->Open(root, &handle, *i, EFI_FILE_MODE_READ, 0);
if (err != EFI_SUCCESS)
@@ -2459,6 +2453,15 @@ static EFI_STATUS initrd_prepare(
if (err != EFI_SUCCESS)
return err;
if (info->FileSize == 0) /* Automatically skip over empty files */
continue;
_cleanup_free_ char16_t *o = options;
if (o)
options = xasprintf("%ls initrd=%ls", o, *i);
else
options = xasprintf("initrd=%ls", *i);
size_t inc = info->FileSize;
if (!INC_SAFE(&padded_size, ALIGN4(inc)))
@@ -2466,6 +2469,14 @@ static EFI_STATUS initrd_prepare(
assert_se(INC_SAFE(&size, *(i + 1) ? ALIGN4(inc) : inc));
}
/* Skip if no valid initrd files */
if (padded_size == 0) {
*ret_options = NULL;
*ret_initrd_pages = (Pages) {};
*ret_initrd_size = 0;
return EFI_SUCCESS;
}
_cleanup_pages_ Pages pages = xmalloc_initrd_pages(padded_size);
uint8_t *p = PHYSICAL_ADDRESS_TO_POINTER(pages.addr);