Unverified Commit 9550374a authored by Emily's avatar Emily Committed by GitHub
Browse files

Revert "systemd: revert boot-breaking systemd-boot change" (#356686)

parents 357e6308 19853b79
Loading
Loading
Loading
Loading
+0 −150
Original line number Diff line number Diff line
From bc1abc37f1cf0368d9c320c9d3845154d85f66b1 Mon Sep 17 00:00:00 2001
From: Alyssa Ross <hi@alyssa.is>
Date: Mon, 11 Nov 2024 23:09:21 +0100
Subject: [PATCH] Revert "boot: Make initrd_prepare() semantically equivalent
 to combine_initrds()"

This reverts commit d64193a2a652b15db9cb9ed10c6b77a17ca46cd2.

This breaks boot on Apple Silicon, and probably other platforms with no memory
mapped below 4G.

Link: https://github.com/systemd/systemd/issues/35026
---
 src/boot/efi/boot.c | 60 ++++++++++++---------------------------------
 1 file changed, 16 insertions(+), 44 deletions(-)

diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c
index ecbb4e0509..f94b59db59 100644
--- a/src/boot/efi/boot.c
+++ b/src/boot/efi/boot.c
@@ -11,7 +11,6 @@
 #include "initrd.h"
 #include "linux.h"
 #include "measure.h"
-#include "memory-util-fundamental.h"
 #include "part-discovery.h"
 #include "pe.h"
 #include "proto/block-io.h"
@@ -2249,18 +2248,18 @@ static EFI_STATUS initrd_prepare(
                 EFI_FILE *root,
                 const BootEntry *entry,
                 char16_t **ret_options,
-                Pages *ret_initrd_pages,
+                void **ret_initrd,
                 size_t *ret_initrd_size) {
 
         assert(root);
         assert(entry);
         assert(ret_options);
-        assert(ret_initrd_pages);
+        assert(ret_initrd);
         assert(ret_initrd_size);
 
         if (entry->type != LOADER_LINUX || !entry->initrd) {
                 *ret_options = NULL;
-                *ret_initrd_pages = (Pages) {};
+                *ret_initrd = NULL;
                 *ret_initrd_size = 0;
                 return EFI_SUCCESS;
         }
@@ -2274,6 +2273,7 @@ static EFI_STATUS initrd_prepare(
 
         EFI_STATUS err;
         size_t size = 0;
+        _cleanup_free_ uint8_t *initrd = NULL;
 
         STRV_FOREACH(i, entry->initrd) {
                 _cleanup_free_ char16_t *o = options;
@@ -2292,58 +2292,30 @@ static EFI_STATUS initrd_prepare(
                 if (err != EFI_SUCCESS)
                         return err;
 
-                if (!INC_SAFE(&size, ALIGN4(info->FileSize)))
-                        return EFI_OUT_OF_RESOURCES;
-        }
-
-        _cleanup_pages_ Pages pages = xmalloc_pages(
-                AllocateMaxAddress,
-                EfiLoaderData,
-                EFI_SIZE_TO_PAGES(size),
-                UINT32_MAX /* Below 4G boundary. */);
-        uint8_t *p = PHYSICAL_ADDRESS_TO_POINTER(pages.addr);
-
-        STRV_FOREACH(i, entry->initrd) {
-                _cleanup_(file_closep) EFI_FILE *handle = NULL;
-                err = root->Open(root, &handle, *i, EFI_FILE_MODE_READ, 0);
-                if (err != EFI_SUCCESS)
-                        return err;
-
-                _cleanup_free_ EFI_FILE_INFO *info = NULL;
-                err = get_file_info(handle, &info, NULL);
-                if (err != EFI_SUCCESS)
-                        return err;
-
                 if (info->FileSize == 0) /* Automatically skip over empty files */
                         continue;
 
-                size_t read_size = info->FileSize;
-                err = chunked_read(handle, &read_size, p);
+                size_t new_size, read_size = info->FileSize;
+                if (!ADD_SAFE(&new_size, size, read_size))
+                        return EFI_OUT_OF_RESOURCES;
+                initrd = xrealloc(initrd, size, new_size);
+
+                err = chunked_read(handle, &read_size, initrd + size);
                 if (err != EFI_SUCCESS)
                         return err;
 
                 /* Make sure the actual read size is what we expected. */
-                assert(read_size == info->FileSize);
-                p += read_size;
-
-                size_t pad;
-                pad = ALIGN4(read_size) - read_size;
-                if (pad == 0)
-                        continue;
-
-                memzero(p, pad);
-                p += pad;
+                assert(size + read_size == new_size);
+                size = new_size;
         }
 
-        assert(PHYSICAL_ADDRESS_TO_POINTER(pages.addr + size) == p);
-
         if (entry->options) {
                 _cleanup_free_ char16_t *o = options;
                 options = xasprintf("%ls %ls", o, entry->options);
         }
 
         *ret_options = TAKE_PTR(options);
-        *ret_initrd_pages = TAKE_STRUCT(pages);
+        *ret_initrd = TAKE_PTR(initrd);
         *ret_initrd_size = size;
         return EFI_SUCCESS;
 }
@@ -2373,9 +2345,9 @@ static EFI_STATUS image_start(
                 return log_error_status(err, "Error making file device path: %m");
 
         size_t initrd_size = 0;
-        _cleanup_pages_ Pages initrd_pages = {};
+        _cleanup_free_ void *initrd = NULL;
         _cleanup_free_ char16_t *options_initrd = NULL;
-        err = initrd_prepare(image_root, entry, &options_initrd, &initrd_pages, &initrd_size);
+        err = initrd_prepare(image_root, entry, &options_initrd, &initrd, &initrd_size);
         if (err != EFI_SUCCESS)
                 return log_error_status(err, "Error preparing initrd: %m");
 
@@ -2393,7 +2365,7 @@ static EFI_STATUS image_start(
         }
 
         _cleanup_(cleanup_initrd) EFI_HANDLE initrd_handle = NULL;
-        err = initrd_register(PHYSICAL_ADDRESS_TO_POINTER(initrd_pages.addr), initrd_size, &initrd_handle);
+        err = initrd_register(initrd, initrd_size, &initrd_handle);
         if (err != EFI_SUCCESS)
                 return log_error_status(err, "Error registering initrd: %m");
 
-- 
2.47.0
+0 −1
Original line number Diff line number Diff line
@@ -232,7 +232,6 @@ stdenv.mkDerivation (finalAttrs: {
    ./0015-tpm2_context_init-fix-driver-name-checking.patch
    ./0016-systemctl-edit-suggest-systemdctl-edit-runtime-on-sy.patch
    ./0017-meson.build-do-not-create-systemdstatedir.patch
    ./0019-Revert-boot-Make-initrd_prepare-semantically-equival.patch

    # https://github.com/systemd/systemd/issues/33392
    (fetchpatch2 {