diff --git a/nixos/tests/systemd-boot-ovmf-broken-fat-driver.patch b/nixos/tests/systemd-boot-ovmf-broken-fat-driver.patch new file mode 100644 index 000000000000..ef547c02f918 --- /dev/null +++ b/nixos/tests/systemd-boot-ovmf-broken-fat-driver.patch @@ -0,0 +1,25 @@ +From d87a7513c6f2f2824203032ef27caeb84892ed7e Mon Sep 17 00:00:00 2001 +From: Will Fancher +Date: Tue, 30 May 2023 16:53:20 -0400 +Subject: [PATCH] Intentionally break the fat driver + +--- + FatPkg/EnhancedFatDxe/ReadWrite.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/FatPkg/EnhancedFatDxe/ReadWrite.c b/FatPkg/EnhancedFatDxe/ReadWrite.c +index 8f525044d1f1..32c62ff7817b 100644 +--- a/FatPkg/EnhancedFatDxe/ReadWrite.c ++++ b/FatPkg/EnhancedFatDxe/ReadWrite.c +@@ -216,6 +216,11 @@ FatIFileAccess ( + Volume = OFile->Volume; + Task = NULL; + ++ if (*BufferSize > (10U * 1024U * 1024U)) { ++ IFile->Position += 10U * 1024U * 1024U; ++ return EFI_BAD_BUFFER_SIZE; ++ } ++ + // + // Write to a directory is unsupported + // diff --git a/nixos/tests/systemd-boot.nix b/nixos/tests/systemd-boot.nix index 94e269ff37bb..19034b299999 100644 --- a/nixos/tests/systemd-boot.nix +++ b/nixos/tests/systemd-boot.nix @@ -251,4 +251,29 @@ in machine.succeed("test -e /boot/efi/nixos/.extra-files/efi/netbootxyz/netboot.xyz.efi") ''; }; + + # See: [Firmware file size bug] in systemd/default.nix + uefiLargeFileWorkaround = makeTest { + name = "uefi-large-file-workaround"; + + nodes.machine = { pkgs, ... }: { + imports = [common]; + virtualisation.efi.OVMF = pkgs.OVMF.overrideAttrs (old: { + # This patch deliberately breaks the FAT driver in EDK2 to + # exhibit (part of) the firmware bug that we are testing + # for. Files greater than 10MiB will fail to be read in a + # single Read() call, so systemd-boot will fail to load the + # initrd without a workaround. The number 10MiB was chosen + # because if it were smaller than the kernel size, even the + # LoadImage call would fail, which is not the failure mode + # we're testing for. It needs to be between the kernel size + # and the initrd size. + patches = old.patches or [] ++ [ ./systemd-boot-ovmf-broken-fat-driver.patch ]; + }); + }; + + testScript = '' + machine.wait_for_unit("multi-user.target") + ''; + }; } diff --git a/pkgs/os-specific/linux/systemd/default.nix b/pkgs/os-specific/linux/systemd/default.nix index fbf56b8c30af..7275d275f74b 100644 --- a/pkgs/os-specific/linux/systemd/default.nix +++ b/pkgs/os-specific/linux/systemd/default.nix @@ -190,6 +190,16 @@ stdenv.mkDerivation (finalAttrs: { ./0017-inherit-systemd-environment-when-calling-generators.patch ./0018-core-don-t-taint-on-unmerged-usr.patch ./0019-tpm2_context_init-fix-driver-name-checking.patch + + (fetchpatch { + # https://github.com/systemd/systemd/pull/25948 + # + # [Firmware file size bug]: Some UEFI firmwares fail on large + # reads. Now that systemd-boot loads initrd itself, systems with + # such firmware won't boot without this fix + url = "https://github.com/systemd/systemd/commit/3ed1d966f00b002ed822ca9de116252bd91fe6c3.patch"; + hash = "sha256-pwXrLTScqgnvfddlzUBZpwsoMrvRLcZPp6e4whMcyL4="; + }) ] ++ lib.optional stdenv.hostPlatform.isMusl ( let oe-core = fetchzip {