diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d03c307e..eb2b8bc0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -102,16 +102,22 @@ jobs: just build-ddi just export-ddi - - name: Build and export live installer & target UKI + - name: Build and export live installer & target UKI, and PXE boot inputs run: | just build-installer - just export-installer + just export-pxe - name: Build and export k0s systemd-sysext run: | just build-sysext just export-sysext + + - name: Build and export Flatcar LTS Kernel & ZFS + run: | + just build-kernel + just build-zfs + just export-kernel - name: Sign release SHA256SUMS manifest if: github.ref == 'refs/heads/main' env: @@ -123,8 +129,11 @@ jobs: # flat manifest at the release root. mkdir -p dist/release cp dist/bluefin-server-installer-*.raw.zst dist/bluefin-server-*.efi dist/release/ + cp dist/bluefin-server-pxe-vmlinuz-* dist/bluefin-server-pxe-initrd-*.cpio.gz dist/release/ cp dist/ddi/bluefin-server-ddi-*.raw.zst dist/release/ - cp dist/sysext/k0s-*.raw.zst dist/release/ + if [ -d dist/kernel ]; then + cp dist/kernel/usr/lib/sysexts/*.raw dist/release/ 2>/dev/null || true + fi (cd dist/release && sha256sum --binary -- * > SHA256SUMS) GNUPGHOME=$(mktemp -d) export GNUPGHOME diff --git a/.github/workflows/kernel.yml b/.github/workflows/kernel.yml new file mode 100644 index 00000000..6d420e86 --- /dev/null +++ b/.github/workflows/kernel.yml @@ -0,0 +1,71 @@ +name: Build Kernel & ZFS + +on: + pull_request: + paths: + - 'elements/flatcar/**' + - 'include/flatcar.yml' + - 'patches/flatcar-kernel/**' + - '.github/workflows/kernel.yml' + - 'Justfile' + push: + branches: [main] + paths: + - 'elements/flatcar/**' + - 'include/flatcar.yml' + - 'patches/flatcar-kernel/**' + - '.github/workflows/kernel.yml' + - 'Justfile' + workflow_dispatch: + +concurrency: + group: kernel-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + build-kernel: + runs-on: ubuntu-24.04 + timeout-minutes: 90 + steps: + - name: Checkout repository + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + ref: ${{ github.event.pull_request.head.ref || github.ref }} + repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }} + + - name: Set up just + uses: taiki-e/install-action@7b8d4719ee4aaa279bdf55df38dacb9ebfe12a6c # v2 + with: + tool: just + + - name: Validate Element Graph + run: just validate + + - name: Set up runner disk space + run: | + set -euo pipefail + sudo mkdir -p /mnt/podman /mnt/buildstream + sudo chown -R "$USER:$USER" /mnt/podman /mnt/buildstream + mkdir -p ~/.config/containers + cat > ~/.config/containers/storage.conf < wrote k0s sysext:" && ls -lh dist/sysext/ +# -- Flatcar LTS kernel & ZFS -------------------------------------------------- +# Build the Flatcar LTS kernel and ZFS sysext. + +# Build the Flatcar LTS kernel binary and modules. +[group('kernel')] +build-kernel: + just bst build flatcar/flatcar-kernel.bst + +# Build the Flatcar ZFS system extension. +[group('kernel')] +build-zfs: + just bst build flatcar/flatcar-zfs.bst + +# Export the kernel and ZFS artifacts to dist/kernel/. +[group('kernel')] +export-kernel: build-kernel build-zfs + rm -rf dist/kernel dist/kernel-checkout dist/zfs-checkout + mkdir -p dist/kernel dist/kernel-checkout dist/zfs-checkout + just bst artifact checkout flatcar/flatcar-kernel.bst --directory /src/dist/kernel-checkout + just bst artifact checkout flatcar/flatcar-zfs.bst --directory /src/dist/zfs-checkout + cp -a dist/kernel-checkout/* dist/kernel/ + cp -a dist/zfs-checkout/* dist/kernel/ + rm -rf dist/kernel-checkout dist/zfs-checkout + (cd dist/kernel && find . -type f -exec sha256sum --binary {} + > SHA256SUMS) + @echo "==> wrote kernel & ZFS artifacts:" && ls -lh dist/kernel/ + # Write the raw GPT installer image to a physical USB drive. [group('installer')] flash-installer DEVICE="": diff --git a/docs/skills/ci-tooling.md b/docs/skills/ci-tooling.md index 9be5404c..6c54c212 100644 --- a/docs/skills/ci-tooling.md +++ b/docs/skills/ci-tooling.md @@ -95,8 +95,9 @@ sudo_cmd := if `podman info >/dev/null 2>&1 && echo 1 || echo 0` == "1" { "" } e | Job | Workflow | Trigger | Purpose | |-----|----------|---------|---------| | `track-refs` | `build.yml` | `pull_request` (`renovate/*` only) | Resolves BuildStream junction refs and pushes them back to the PR branch. Sole `contents: write` grant on `pull_request`. | -| `build` | `build.yml` | `pull_request`, `push/main`, `workflow_dispatch` | Resolves the element graph, runs the full BuildStream compile, and signs the release manifest on pushes to `main`. Read-only token. | +| `build` | `build.yml` | `pull_request`, `push/main`, `workflow_dispatch` | Resolves the element graph, runs the full BuildStream compile (including Flatcar LTS Kernel & ZFS), and signs the release manifest on pushes to `main`. Read-only token. | | `release` | `build.yml` | `push/main`, `workflow_dispatch` | Downloads the signed assets handed off by `build` and publishes them to the GitHub Release (`if: ${{ !failure() && !cancelled() && github.ref == 'refs/heads/main' }}`). `contents: write`. | +| `build-kernel` | `kernel.yml` | `pull_request` (paths: `elements/flatcar/**`, `include/flatcar.yml`, `patches/flatcar-kernel/**`), `push/main`, `workflow_dispatch` | Standalone kernel & OpenZFS sysext BuildStream build and export. Emits `dist/kernel/` artifacts. Read-only token. | | `docs` | `docs-checks.yml` | `pull_request`, `push/main` | Runs markdown and skill metadata checks via `docs-checks.py`. Read-only token. | | `unit` | `unit-tests.yml` | `pull_request`, `push/main` | Runs pytest and BATS unit test suites. Read-only token. | diff --git a/docs/skills/ddi-installer-build.md b/docs/skills/ddi-installer-build.md index c5c3446b..79048be3 100644 --- a/docs/skills/ddi-installer-build.md +++ b/docs/skills/ddi-installer-build.md @@ -23,6 +23,7 @@ just validate # resolve the BuildStream graph just cluster-build # submit an Argo workflow to build/publish just build-installer # build the installer locally just export-installer # export installer + UKI + SHA256SUMS to dist/ +just export-pxe # export standalone PXE vmlinuz/initrd to dist/ just build-ddi # build the OS DDI payload just export-ddi # export DDI + SHA256SUMS to dist/ddi/ just build-sysext # build the k0s sysext @@ -87,11 +88,13 @@ Use direct I/O and full-block reads to avoid dirtying the page cache. The release process is driven by `.github/workflows/build.yml`: - Renovate point-release updates or direct pushes to `main` trigger a full build. -- CI builds the DDI payload, installer, target UKI, and k0s sysext. +- CI builds the DDI payload, installer, target UKI, k0s sysext, and standalone + PXE boot inputs (`bluefin-server-pxe-vmlinuz-*`, `bluefin-server-pxe-initrd-*.cpio.gz`). - CI uploads the versioned release assets to the corresponding `installer-v` GitHub Release. - CI also produces a combined `dist/release/SHA256SUMS` manifest and signs it - to create `SHA256SUMS.gpg` for `systemd-sysupdate` verification. + to create `SHA256SUMS.gpg` for `systemd-sysupdate` verification. The PXE + inputs are included in this manifest, per `docs/skills/ddi-installer.md`. ## Common rationalizations diff --git a/elements/bluefin-server/os-release-flatcar.bst b/elements/bluefin-server/os-release-flatcar.bst index c6435220..c90ae7d4 100644 --- a/elements/bluefin-server/os-release-flatcar.bst +++ b/elements/bluefin-server/os-release-flatcar.bst @@ -1,8 +1,9 @@ kind: manual description: Create custom Flatcar-compatible os-release metadata to support Flatcar system extensions (sysext). -# %{flatcar-board} — derived from the `arch` option, never hardcoded here. -(@): include/arch.yml +(@): + - include/arch.yml + - include/flatcar.yml build-depends: # Base runtime providing /bin/sh and coreutils (cat, ln, mkdir, sed) in the sandbox. @@ -36,7 +37,7 @@ config: fi # Flatcar-compatible version used by systemd-sysext / Flatcar Bakery matching. - FLATCAR_VERSION="4593.2.3" + FLATCAR_VERSION="%{flatcar-version}" cat < "%{install-root}/usr/lib/os-release" NAME="Bluefin Server" diff --git a/elements/bluefin-server/os-stack.bst b/elements/bluefin-server/os-stack.bst index 004c09ff..bc79fe4d 100644 --- a/elements/bluefin-server/os-stack.bst +++ b/elements/bluefin-server/os-stack.bst @@ -25,8 +25,9 @@ depends: - bluefin-server/os-sshd-preset.bst - bluefin-server/os-sshd-config.bst - # Stock FSDK Kernel & Server-Chiseled Firmware - - freedesktop-sdk.bst:components/linux.bst + # Flatcar LTS Kernel & Matching ZFS + - flatcar/flatcar-kernel.bst + - flatcar/flatcar-zfs.bst - bluefin-server/linux-firmware-split.bst # Filesystem resizing support for growing root/var on first boot diff --git a/elements/flatcar/flatcar-kernel.bst b/elements/flatcar/flatcar-kernel.bst new file mode 100644 index 00000000..7a9ea9ab --- /dev/null +++ b/elements/flatcar/flatcar-kernel.bst @@ -0,0 +1,58 @@ +kind: manual +description: | + Import the Flatcar LTS Linux Kernel binary (vmlinuz) and matching module tree. + Contains all upstream Flatcar kernel patches (EFI secure boot lockdown, partition UUID uevents, + reproducible pahole builds, relative srctree kbuild). + Pinned in lockstep with the Flatcar release version defined in include/flatcar.yml. + +(@): + - include/arch.yml + - include/flatcar.yml + +build-depends: + - base/base-stack.bst + - freedesktop-sdk.bst:components/tar.bst + - freedesktop-sdk.bst:components/gzip.bst + - freedesktop-sdk.bst:components/xz.bst + - freedesktop-sdk.bst:components/findutils.bst + +variables: + strip-binaries: "" + +sources: + - kind: remote + url: flatcar:stable/%{flatcar-board}/%{flatcar-version}/flatcar_production_image.vmlinuz + ref: fe0b7ef1f9f98acc00e1db22937cdc57456df860a372fdc8eb806298f767b676 + - kind: remote + url: flatcar:stable/%{flatcar-board}/%{flatcar-version}/flatcar-container.tar.gz + ref: c533ff576e128d11ce240e01f818c358d75b9ff118b2dd9199fbf4684547a32c + - kind: local + path: patches/flatcar-kernel + directory: patches + +config: + install-commands: + - | + set -euo pipefail + + TARGET_MODDIR="%{install-root}/usr/lib/modules/%{flatcar-kver}" + mkdir -p "${TARGET_MODDIR}" + + # Install the kernel binary + install -D -m 0644 flatcar_production_image.vmlinuz "${TARGET_MODDIR}/vmlinuz" + + # Extract modules from container rootfs + tar -zxvf flatcar-container.tar.gz \ + --strip-components=4 \ + -C "${TARGET_MODDIR}" \ + "./usr/lib/modules/%{flatcar-kver}" + + # Uncompress .xz modules so dracut, depmod, and kmod can handle them consistently + find "${TARGET_MODDIR}" -type f -name '*.ko.xz' -exec unxz {} + + + # Strip vmlinux and System.map if present to save image footprint + rm -f "${TARGET_MODDIR}/vmlinux" "${TARGET_MODDIR}/System.map" + + # Stage Flatcar kernel patchset for reference and downstream builds + mkdir -p "%{install-root}/usr/src/flatcar-kernel-patches" + cp -a patches/*.patch "%{install-root}/usr/src/flatcar-kernel-patches/" diff --git a/elements/flatcar/flatcar-zfs.bst b/elements/flatcar/flatcar-zfs.bst new file mode 100644 index 00000000..82832969 --- /dev/null +++ b/elements/flatcar/flatcar-zfs.bst @@ -0,0 +1,33 @@ +kind: manual +description: | + Import and extract the Flatcar ZFS system extension (sysext). + Provides spl.ko and zfs.ko modules matching the Flatcar LTS kernel, + along with upstream zpool, zfs userspace tools, systemd services, and udev rules. + +(@): + - include/arch.yml + - include/flatcar.yml + +build-depends: + - base/base-stack.bst + - freedesktop-sdk.bst:components/squashfs-tools.bst + +variables: + strip-binaries: "" + +sources: + - kind: remote + url: flatcar:stable/%{flatcar-board}/%{flatcar-version}/flatcar-zfs.raw + ref: bed24d0a31b6c9ff0f1d59ec2b50d25585bf9bbcb8e9e96f5706f1a17948d971 + +config: + install-commands: + - | + set -euo pipefail + + # Extract the SquashFS sysext directly into the element install root + unsquashfs -no-xattrs -f -d "%{install-root}" flatcar-zfs.raw + + # Also preserve the raw sysext image under /usr/lib/sysexts for runtime sysext usage + mkdir -p "%{install-root}/usr/lib/sysexts" + install -D -m 0644 flatcar-zfs.raw "%{install-root}/usr/lib/sysexts/zfs.raw" diff --git a/elements/installer/installer-stack.bst b/elements/installer/installer-stack.bst index 3168b517..49a74955 100644 --- a/elements/installer/installer-stack.bst +++ b/elements/installer/installer-stack.bst @@ -35,7 +35,8 @@ depends: - freedesktop-sdk.bst:components/dosfstools.bst # Kernel (installer boots from this; vmlinuz used as the UKI --linux= arg) - - freedesktop-sdk.bst:components/linux.bst + - flatcar/flatcar-kernel.bst + - flatcar/flatcar-zfs.bst # repart.d configs describing the TARGET disk layout - installer/installer-repart.bst diff --git a/elements/oci/bluefin-server-installer.bst b/elements/oci/bluefin-server-installer.bst index a505db13..b85bbb75 100644 --- a/elements/oci/bluefin-server-installer.bst +++ b/elements/oci/bluefin-server-installer.bst @@ -125,8 +125,8 @@ config: # Run dracut in generic (non-hostonly) mode and explicitly add XFS, VirtIO, and NVMe storage drivers. dracut -v --reproducible --no-machineid --no-hostonly \ - --add-drivers "virtio virtio_blk virtio_pci virtio_scsi nvme nvme_core xfs erofs overlay" \ - --filesystems "xfs vfat" \ + --add-drivers "virtio virtio_blk virtio_pci virtio_scsi nvme nvme_core xfs erofs overlay zfs spl" \ + --filesystems "xfs vfat zfs" \ --install /etc/ld.so.cache \ --kmoddir "/target-root/usr/lib/modules/${TARGET_KVER}" \ --kernel-image "${TARGET_KERNEL}" \ diff --git a/include/aliases.yml b/include/aliases.yml index d2eb758f..6ff26ed3 100644 --- a/include/aliases.yml +++ b/include/aliases.yml @@ -6,3 +6,4 @@ aliases: gitlab: https://gitlab.com/ gnome: https://gitlab.gnome.org/GNOME/ crates: https://static.crates.io/ + flatcar: https://flatcar.cdn.cncf.io/ diff --git a/include/flatcar.yml b/include/flatcar.yml new file mode 100644 index 00000000..e8f7cb08 --- /dev/null +++ b/include/flatcar.yml @@ -0,0 +1,7 @@ +# Single source of truth for Flatcar LTS kernel and sysext versioning. +# +# Flatcar LTS kernel and ZFS sysext must stay strictly in lockstep because +# OpenZFS modules (spl.ko, zfs.ko) require matching kernel vermagic (6.12.102-flatcar). +variables: + flatcar-version: "4593.2.5" + flatcar-kver: "6.12.102-flatcar" diff --git a/patches/flatcar-kernel/z0001-kbuild-derive-relative-path-for-srctree-from-CURDIR.patch b/patches/flatcar-kernel/z0001-kbuild-derive-relative-path-for-srctree-from-CURDIR.patch new file mode 100644 index 00000000..8f269fd9 --- /dev/null +++ b/patches/flatcar-kernel/z0001-kbuild-derive-relative-path-for-srctree-from-CURDIR.patch @@ -0,0 +1,33 @@ +From dcf70e8275cf5cc964a0657312af9210996ae2e7 Mon Sep 17 00:00:00 2001 +From: Vito Caputo +Date: Wed, 25 Nov 2015 02:59:45 -0800 +Subject: [PATCH 1/2] kbuild: derive relative path for srctree from CURDIR + +This enables relocating source and build trees to different roots, +provided they stay reachable relative to one another. Useful for +builds done within a sandbox where the eventual root is prefixed +by some undesirable path component. +--- + Makefile | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/Makefile b/Makefile +index a5cfcd0a85a9..b81055b65169 100644 +--- a/Makefile ++++ b/Makefile +@@ -262,8 +262,10 @@ else + building_out_of_srctree := 1 + endif + +-ifneq ($(KBUILD_ABS_SRCTREE),) +-srctree := $(abs_srctree) ++ifneq ($(KBUILD_OUTPUT),) ++ srctree := $(shell realpath --relative-to=$(KBUILD_OUTPUT) $(abs_srctree)) ++else ++ srctree := $(abs_srctree) + endif + + objtree := . +-- +2.25.1 + diff --git a/patches/flatcar-kernel/z0002-pahole-support-reproducible-builds.patch b/patches/flatcar-kernel/z0002-pahole-support-reproducible-builds.patch new file mode 100644 index 00000000..dbce2286 --- /dev/null +++ b/patches/flatcar-kernel/z0002-pahole-support-reproducible-builds.patch @@ -0,0 +1,26 @@ +From 9faff3734e6456e7927c0914829a4764ec9f1b44 Mon Sep 17 00:00:00 2001 +From: Adrian Vladu +Date: Tue, 17 Sep 2024 13:44:14 +0000 +Subject: [PATCH] pahole: support reproducible builds + +--- + scripts/Makefile.btf | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/scripts/Makefile.btf b/scripts/Makefile.btf +index 2d6e5ed9081e..b2f88b0fcf37 100644 +--- a/scripts/Makefile.btf ++++ b/scripts/Makefile.btf +@@ -23,6 +23,9 @@ else + # Switch to using --btf_features for v1.26 and later. + pahole-flags-$(call test-ge, $(pahole-ver), 126) = -j --btf_features=encode_force,var,float,enum64,decl_tag,type_tag,optimized_func,consistent_func + ++# Support reproducible builds. ++pahole-flags-$(call test-ge, $(pahole-ver), 127) = -j --btf_features=encode_force,var,float,enum64,decl_tag,type_tag,optimized_func,consistent_func,reproducible_build ++ + endif + + pahole-flags-$(CONFIG_PAHOLE_HAS_LANG_EXCLUDE) += --lang_exclude=rust +-- +2.34.1 + diff --git a/patches/flatcar-kernel/z0003-Revert-x86-boot-Remove-the-bugger-off-message.patch b/patches/flatcar-kernel/z0003-Revert-x86-boot-Remove-the-bugger-off-message.patch new file mode 100644 index 00000000..6f3a7370 --- /dev/null +++ b/patches/flatcar-kernel/z0003-Revert-x86-boot-Remove-the-bugger-off-message.patch @@ -0,0 +1,103 @@ +From 9f34a9ffe5b94aee93baa5762719546e0bebc28d Mon Sep 17 00:00:00 2001 +From: Kai Lueke +Date: Fri, 15 Mar 2024 11:49:50 +0100 +Subject: [PATCH] Revert "x86/boot: Remove the 'bugger off' message" + +This reverts commit 768171d7ebbce005210e1cf8456f043304805c15 because for +now this is still needed to store the dm-verity hash. +--- + arch/x86/boot/header.S | 49 ++++++++++++++++++++++++++++++++++++++++++ + arch/x86/boot/setup.ld | 7 +++--- + 2 files changed, 52 insertions(+), 4 deletions(-) + +diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S +index a1bbedd989e4..c7624caf6840 100644 +--- a/arch/x86/boot/header.S ++++ b/arch/x86/boot/header.S +@@ -41,15 +41,64 @@ SYSSEG = 0x1000 /* historical load address >> 4 */ + + .code16 + .section ".bstext", "ax" ++ ++ .global bootsect_start ++bootsect_start: + #ifdef CONFIG_EFI_STUB + # "MZ", MS-DOS header + .word MZ_MAGIC ++#endif ++ ++ # Normalize the start address ++ ljmp $BOOTSEG, $start2 ++ ++start2: ++ movw %cs, %ax ++ movw %ax, %ds ++ movw %ax, %es ++ movw %ax, %ss ++ xorw %sp, %sp ++ sti ++ cld ++ ++ movw $bugger_off_msg, %si ++ ++msg_loop: ++ lodsb ++ andb %al, %al ++ jz bs_die ++ movb $0xe, %ah ++ movw $7, %bx ++ int $0x10 ++ jmp msg_loop ++ ++bs_die: ++ # Allow the user to press a key, then reboot ++ xorw %ax, %ax ++ int $0x16 ++ int $0x19 ++ ++ # int 0x19 should never return. In case it does anyway, ++ # invoke the BIOS reset code... ++ ljmp $0xf000,$0xfff0 ++ ++#ifdef CONFIG_EFI_STUB + .org 0x38 + # + # Offset to the PE header. + # + .long LINUX_PE_MAGIC + .long pe_header ++#endif /* CONFIG_EFI_STUB */ ++ ++ .section ".bsdata", "a" ++bugger_off_msg: ++ .ascii "Use a boot loader.\r\n" ++ .ascii "\n" ++ .ascii "Remove disk and press any key to reboot...\r\n" ++ .byte 0 ++ ++#ifdef CONFIG_EFI_STUB + pe_header: + .long PE_MAGIC + +diff --git a/arch/x86/boot/setup.ld b/arch/x86/boot/setup.ld +index 3a2d1360abb0..c3e354d312d0 100644 +--- a/arch/x86/boot/setup.ld ++++ b/arch/x86/boot/setup.ld +@@ -10,11 +10,10 @@ ENTRY(_start) + SECTIONS + { + . = 0; +- .bstext : { +- *(.bstext) +- . = 495; +- } =0xffffffff ++ .bstext : { *(.bstext) } ++ .bsdata : { *(.bsdata) } + ++ . = 495; + .header : { *(.header) } + .entrytext : { *(.entrytext) } + .inittext : { *(.inittext) } +-- +2.44.0 + diff --git a/patches/flatcar-kernel/z0004-efi-add-an-efi_secure_boot-flag-to-indicate-secure-b.patch b/patches/flatcar-kernel/z0004-efi-add-an-efi_secure_boot-flag-to-indicate-secure-b.patch new file mode 100644 index 00000000..822beab2 --- /dev/null +++ b/patches/flatcar-kernel/z0004-efi-add-an-efi_secure_boot-flag-to-indicate-secure-b.patch @@ -0,0 +1,153 @@ +From: David Howells +Date: Mon, 18 Feb 2019 12:45:03 +0000 +Subject: [28/30] efi: Add an EFI_SECURE_BOOT flag to indicate secure boot mode +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=a5d70c55c603233c192b375f72116a395909da28 + +UEFI machines can be booted in Secure Boot mode. Add an EFI_SECURE_BOOT +flag that can be passed to efi_enabled() to find out whether secure boot is +enabled. + +Move the switch-statement in x86's setup_arch() that inteprets the +secure_boot boot parameter to generic code and set the bit there. + +Suggested-by: Ard Biesheuvel +Signed-off-by: David Howells +Reviewed-by: Ard Biesheuvel +cc: linux-efi@vger.kernel.org +[rperier: Forward-ported to 5.5: + - Use pr_warn() + - Adjust context] +[bwh: Forward-ported to 5.6: adjust context] +[bwh: Forward-ported to 5.7: + - Use the next available bit in efi.flags + - Adjust context] +--- + arch/x86/kernel/setup.c | 14 +---------- + drivers/firmware/efi/Makefile | 1 + + drivers/firmware/efi/secureboot.c | 39 +++++++++++++++++++++++++++++++ + include/linux/efi.h | 16 ++++++++----- + 4 files changed, 51 insertions(+), 19 deletions(-) + create mode 100644 drivers/firmware/efi/secureboot.c + +--- a/arch/x86/kernel/setup.c ++++ b/arch/x86/kernel/setup.c +@@ -1193,19 +1193,7 @@ void __init setup_arch(char **cmdline_p) + /* Allocate bigger log buffer */ + setup_log_buf(1); + +- if (efi_enabled(EFI_BOOT)) { +- switch (boot_params.secure_boot) { +- case efi_secureboot_mode_disabled: +- pr_info("Secure boot disabled\n"); +- break; +- case efi_secureboot_mode_enabled: +- pr_info("Secure boot enabled\n"); +- break; +- default: +- pr_info("Secure boot could not be determined\n"); +- break; +- } +- } ++ efi_set_secure_boot(boot_params.secure_boot); + + reserve_initrd(); + +--- a/drivers/firmware/efi/Makefile ++++ b/drivers/firmware/efi/Makefile +@@ -25,6 +25,7 @@ obj-$(CONFIG_EFI_FAKE_MEMMAP) += fake_m + obj-$(CONFIG_EFI_BOOTLOADER_CONTROL) += efibc.o + obj-$(CONFIG_EFI_TEST) += test/ + obj-$(CONFIG_EFI_DEV_PATH_PARSER) += dev-path-parser.o ++obj-$(CONFIG_EFI) += secureboot.o + obj-$(CONFIG_APPLE_PROPERTIES) += apple-properties.o + obj-$(CONFIG_EFI_RCI2_TABLE) += rci2-table.o + obj-$(CONFIG_EFI_EMBEDDED_FIRMWARE) += embedded-firmware.o +--- /dev/null ++++ b/drivers/firmware/efi/secureboot.c +@@ -0,0 +1,39 @@ ++ ++/* Core kernel secure boot support. ++ * ++ * Copyright (C) 2017 Red Hat, Inc. All Rights Reserved. ++ * Written by David Howells (dhowells@redhat.com) ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public Licence ++ * as published by the Free Software Foundation; either version ++ * 2 of the Licence, or (at your option) any later version. ++ */ ++ ++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt ++ ++#include ++#include ++#include ++ ++/* ++ * Decide what to do when UEFI secure boot mode is enabled. ++ */ ++void __init efi_set_secure_boot(enum efi_secureboot_mode mode) ++{ ++ if (efi_enabled(EFI_BOOT)) { ++ switch (mode) { ++ case efi_secureboot_mode_disabled: ++ pr_info("Secure boot disabled\n"); ++ break; ++ case efi_secureboot_mode_enabled: ++ set_bit(EFI_SECURE_BOOT, &efi.flags); ++ pr_info("Secure boot enabled\n"); ++ break; ++ default: ++ pr_warn("Secure boot could not be determined (mode %u)\n", ++ mode); ++ break; ++ } ++ } ++} +--- a/include/linux/efi.h ++++ b/include/linux/efi.h +@@ -871,6 +871,14 @@ extern int __init efi_setup_pcdp_console + #define EFI_MEM_ATTR 10 /* Did firmware publish an EFI_MEMORY_ATTRIBUTES table? */ + #define EFI_MEM_NO_SOFT_RESERVE 11 /* Is the kernel configured to ignore soft reservations? */ + #define EFI_PRESERVE_BS_REGIONS 12 /* Are EFI boot-services memory segments available? */ ++#define EFI_SECURE_BOOT 13 /* Are we in Secure Boot mode? */ ++ ++enum efi_secureboot_mode { ++ efi_secureboot_mode_unset, ++ efi_secureboot_mode_unknown, ++ efi_secureboot_mode_disabled, ++ efi_secureboot_mode_enabled, ++}; + + #ifdef CONFIG_EFI + /* +@@ -895,6 +903,7 @@ static inline bool efi_rt_services_suppo + return (efi.runtime_supported_mask & mask) == mask; + } + extern void efi_find_mirror(void); ++extern void __init efi_set_secure_boot(enum efi_secureboot_mode mode); + #else + static inline bool efi_enabled(int feature) + { +@@ -914,6 +923,7 @@ static inline bool efi_rt_services_suppo + } + + static inline void efi_find_mirror(void) {} ++static inline void efi_set_secure_boot(enum efi_secureboot_mode mode) {} + #endif + + extern int efi_status_to_err(efi_status_t status); +@@ -1133,13 +1143,6 @@ static inline bool efi_runtime_disabled( + extern void efi_call_virt_check_flags(unsigned long flags, const void *caller); + extern unsigned long efi_call_virt_save_flags(void); + +-enum efi_secureboot_mode { +- efi_secureboot_mode_unset, +- efi_secureboot_mode_unknown, +- efi_secureboot_mode_disabled, +- efi_secureboot_mode_enabled, +-}; +- + static inline + enum efi_secureboot_mode efi_get_secureboot_mode(efi_get_variable_t *get_var) + { diff --git a/patches/flatcar-kernel/z0005-efi-lock-down-the-kernel-if-booted-in-secure-boot-mo.patch b/patches/flatcar-kernel/z0005-efi-lock-down-the-kernel-if-booted-in-secure-boot-mo.patch new file mode 100644 index 00000000..6fff3f89 --- /dev/null +++ b/patches/flatcar-kernel/z0005-efi-lock-down-the-kernel-if-booted-in-secure-boot-mo.patch @@ -0,0 +1,121 @@ +From: Ben Hutchings +Date: Tue, 10 Sep 2019 11:54:28 +0100 +Subject: efi: Lock down the kernel if booted in secure boot mode + +Based on an earlier patch by David Howells, who wrote the following +description: + +> UEFI Secure Boot provides a mechanism for ensuring that the firmware will +> only load signed bootloaders and kernels. Certain use cases may also +> require that all kernel modules also be signed. Add a configuration option +> that to lock down the kernel - which includes requiring validly signed +> modules - if the kernel is secure-booted. + +Signed-off-by: Ben Hutchings +[Salvatore Bonaccorso: After fixing https://bugs.debian.org/956197 the +help text for LOCK_DOWN_IN_EFI_SECURE_BOOT was adjusted to mention that +lockdown is triggered in integrity mode (https://bugs.debian.org/1025417)] +Signed-off-by: Salvatore Bonaccorso +--- + arch/x86/kernel/setup.c | 4 ++-- + drivers/firmware/efi/secureboot.c | 3 +++ + include/linux/security.h | 6 ++++++ + security/lockdown/Kconfig | 15 +++++++++++++++ + security/lockdown/lockdown.c | 2 +- + 5 files changed, 27 insertions(+), 3 deletions(-) + +--- a/arch/x86/kernel/setup.c ++++ b/arch/x86/kernel/setup.c +@@ -904,6 +904,8 @@ void __init setup_arch(char **cmdline_p) + if (efi_enabled(EFI_BOOT)) + efi_init(); + ++ efi_set_secure_boot(boot_params.secure_boot); ++ + reserve_ibft_region(); + x86_init.resources.dmi_setup(); + +@@ -1070,8 +1072,6 @@ void __init setup_arch(char **cmdline_p) + /* Allocate bigger log buffer */ + setup_log_buf(1); + +- efi_set_secure_boot(boot_params.secure_boot); +- + reserve_initrd(); + + acpi_table_upgrade(); +--- a/drivers/firmware/efi/secureboot.c ++++ b/drivers/firmware/efi/secureboot.c +@@ -15,6 +15,7 @@ + #include + #include + #include ++#include + + /* + * Decide what to do when UEFI secure boot mode is enabled. +@@ -28,6 +29,10 @@ void __init efi_set_secure_boot(enum efi + break; + case efi_secureboot_mode_enabled: + set_bit(EFI_SECURE_BOOT, &efi.flags); ++#ifdef CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT ++ lock_kernel_down("EFI Secure Boot", ++ LOCKDOWN_INTEGRITY_MAX); ++#endif + pr_info("Secure boot enabled\n"); + break; + default: +--- a/include/linux/security.h ++++ b/include/linux/security.h +@@ -522,6 +522,7 @@ int security_inode_notifysecctx(struct i + int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen); + int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen); + int security_locked_down(enum lockdown_reason what); ++int lock_kernel_down(const char *where, enum lockdown_reason level); + int lsm_fill_user_ctx(struct lsm_ctx __user *uctx, u32 *uctx_len, + void *val, size_t val_len, u64 id, u64 flags); + int security_bdev_alloc(struct block_device *bdev); +@@ -1504,6 +1505,11 @@ static inline int security_locked_down(e + { + return 0; + } ++static inline int ++lock_kernel_down(const char *where, enum lockdown_reason level) ++{ ++ return -EOPNOTSUPP; ++} + static inline int lsm_fill_user_ctx(struct lsm_ctx __user *uctx, + u32 *uctx_len, void *val, size_t val_len, + u64 id, u64 flags) +--- a/security/lockdown/Kconfig ++++ b/security/lockdown/Kconfig +@@ -45,3 +45,18 @@ config LOCK_DOWN_KERNEL_FORCE_CONFIDENTI + disabled. + + endchoice ++ ++config LOCK_DOWN_IN_EFI_SECURE_BOOT ++ bool "Lock down the kernel in EFI Secure Boot mode" ++ default n ++ depends on SECURITY_LOCKDOWN_LSM ++ depends on EFI ++ select SECURITY_LOCKDOWN_LSM_EARLY ++ help ++ UEFI Secure Boot provides a mechanism for ensuring that the firmware ++ will only load signed bootloaders and kernels. Secure boot mode may ++ be determined from EFI variables provided by the system firmware if ++ not indicated by the boot parameters. ++ ++ Enabling this option results in kernel lockdown being ++ triggered in integrity mode if EFI Secure Boot is set. +--- a/security/lockdown/lockdown.c ++++ b/security/lockdown/lockdown.c +@@ -24,7 +24,7 @@ static const enum lockdown_reason lockdo + /* + * Put the kernel into lock-down mode. + */ +-static int lock_kernel_down(const char *where, enum lockdown_reason level) ++int lock_kernel_down(const char *where, enum lockdown_reason level) + { + if (kernel_locked_down >= level) + return -EPERM; diff --git a/patches/flatcar-kernel/z0006-mtd-disable-slram-and-phram-when-locked-down.patch b/patches/flatcar-kernel/z0006-mtd-disable-slram-and-phram-when-locked-down.patch new file mode 100644 index 00000000..c718e7e2 --- /dev/null +++ b/patches/flatcar-kernel/z0006-mtd-disable-slram-and-phram-when-locked-down.patch @@ -0,0 +1,75 @@ +From: Ben Hutchings +Date: Fri, 30 Aug 2019 15:54:24 +0100 +Subject: mtd: phram,slram: Disable when the kernel is locked down +Forwarded: https://lore.kernel.org/linux-security-module/20190830154720.eekfjt6c4jzvlbfz@decadent.org.uk/ + +These drivers allow mapping arbitrary memory ranges as MTD devices. +This should be disabled to preserve the kernel's integrity when it is +locked down. + +* Add the HWPARAM flag to the module parameters +* When slram is built-in, it uses __setup() to read kernel parameters, + so add an explicit check security_locked_down() check + +Signed-off-by: Ben Hutchings +Cc: Matthew Garrett +Cc: David Howells +Cc: Joern Engel +Cc: linux-mtd@lists.infradead.org +--- + drivers/mtd/devices/phram.c | 6 +++++- + drivers/mtd/devices/slram.c | 9 ++++++++- + 2 files changed, 13 insertions(+), 2 deletions(-) + +--- a/drivers/mtd/devices/phram.c ++++ b/drivers/mtd/devices/phram.c +@@ -364,7 +364,11 @@ static int phram_param_call(const char * + #endif + } + +-module_param_call(phram, phram_param_call, NULL, NULL, 0200); ++static const struct kernel_param_ops phram_param_ops = { ++ .set = phram_param_call ++}; ++__module_param_call(MODULE_PARAM_PREFIX, phram, &phram_param_ops, NULL, ++ 0200, -1, KERNEL_PARAM_FL_HWPARAM | hwparam_iomem); + MODULE_PARM_DESC(phram, "Memory region to map. \"phram=,,[,]\""); + + #ifdef CONFIG_OF +--- a/drivers/mtd/devices/slram.c ++++ b/drivers/mtd/devices/slram.c +@@ -43,6 +43,7 @@ + #include + #include + #include ++#include + + #include + +@@ -65,7 +66,7 @@ typedef struct slram_mtd_list { + #ifdef MODULE + static char *map[SLRAM_MAX_DEVICES_PARAMS]; + +-module_param_array(map, charp, NULL, 0); ++module_param_hw_array(map, charp, iomem, NULL, 0); + MODULE_PARM_DESC(map, "List of memory regions to map. \"map=, , \""); + #else + static char *map; +@@ -281,11 +282,17 @@ static int __init init_slram(void) + #ifndef MODULE + char *devstart; + char *devlength; ++ int ret; + + if (!map) { + E("slram: not enough parameters.\n"); + return(-EINVAL); + } ++ ++ ret = security_locked_down(LOCKDOWN_MODULE_PARAMETERS); ++ if (ret) ++ return ret; ++ + while (map) { + devname = devstart = devlength = NULL; + diff --git a/patches/flatcar-kernel/z0007-arm64-add-kernel-config-option-to-lock-down-when.patch b/patches/flatcar-kernel/z0007-arm64-add-kernel-config-option-to-lock-down-when.patch new file mode 100644 index 00000000..61b70409 --- /dev/null +++ b/patches/flatcar-kernel/z0007-arm64-add-kernel-config-option-to-lock-down-when.patch @@ -0,0 +1,153 @@ +From: Linn Crosetto +Date: Tue, 30 Aug 2016 11:54:38 -0600 +Subject: arm64: add kernel config option to lock down when in Secure Boot mode +Bug-Debian: https://bugs.debian.org/831827 +Forwarded: no + +Add a kernel configuration option to lock down the kernel, to restrict +userspace's ability to modify the running kernel when UEFI Secure Boot is +enabled. Based on the x86 patch by Matthew Garrett. + +Determine the state of Secure Boot in the EFI stub and pass this to the +kernel using the FDT. + +Signed-off-by: Linn Crosetto +[bwh: Forward-ported to 4.10: adjust context] +[Lukas Wunner: Forward-ported to 4.11: drop parts applied upstream] +[bwh: Forward-ported to 4.15 and lockdown patch set: + - Pass result of efi_get_secureboot() in stub through to + efi_set_secure_boot() in main kernel + - Use lockdown API and naming] +[bwh: Forward-ported to 4.19.3: adjust context in update_fdt()] +[dannf: Moved init_lockdown() call after uefi_init(), fixing SB detection] +[bwh: Drop call to init_lockdown(), as efi_set_secure_boot() now calls this] +[bwh: Forward-ported to 5.6: efi_get_secureboot() no longer takes a + sys_table parameter] +[bwh: Forward-ported to 5.7: EFI initialisation from FDT was rewritten, so: + - Add Secure Boot mode to the parameter enumeration in fdtparams.c + - Add a parameter to efi_get_fdt_params() to return the Secure Boot mode + - Since Xen does not have a property name defined for Secure Boot mode, + change efi_get_fdt_prop() to handle a missing property name by clearing + the output variable] +[Salvatore Bonaccorso: Forward-ported to 5.10: f30f242fb131 ("efi: Rename +arm-init to efi-init common for all arch") renamed arm-init.c to efi-init.c] +--- + drivers/firmware/efi/efi-init.c | 5 ++++- + drivers/firmware/efi/fdtparams.c | 12 +++++++++++- + drivers/firmware/efi/libstub/fdt.c | 6 ++++++ + include/linux/efi.h | 3 ++- + 4 files changed, 23 insertions(+), 3 deletions(-) + +--- a/drivers/firmware/efi/efi-init.c ++++ b/drivers/firmware/efi/efi-init.c +@@ -213,9 +213,10 @@ void __init efi_init(void) + { + struct efi_memory_map_data data; + u64 efi_system_table; ++ u32 secure_boot; + + /* Grab UEFI information placed in FDT by stub */ +- efi_system_table = efi_get_fdt_params(&data); ++ efi_system_table = efi_get_fdt_params(&data, &secure_boot); + if (!efi_system_table) + return; + +@@ -237,6 +238,8 @@ void __init efi_init(void) + return; + } + ++ efi_set_secure_boot(secure_boot); ++ + reserve_regions(); + /* + * For memblock manipulation, the cap should come after the memblock_add(). +--- a/drivers/firmware/efi/fdtparams.c ++++ b/drivers/firmware/efi/fdtparams.c +@@ -16,6 +16,7 @@ enum { + MMSIZE, + DCSIZE, + DCVERS, ++ SBMODE, + + PARAMCOUNT + }; +@@ -26,6 +27,7 @@ static __initconst const char name[][22] + [MMSIZE] = "MemMap Size ", + [DCSIZE] = "MemMap Desc. Size ", + [DCVERS] = "MemMap Desc. Version ", ++ [SBMODE] = "Secure Boot Enabled ", + }; + + static __initconst const struct { +@@ -43,6 +45,7 @@ static __initconst const struct { + [MMSIZE] = "xen,uefi-mmap-size", + [DCSIZE] = "xen,uefi-mmap-desc-size", + [DCVERS] = "xen,uefi-mmap-desc-ver", ++ [SBMODE] = "", + } + }, { + #endif +@@ -53,6 +56,7 @@ static __initconst const struct { + [MMSIZE] = "linux,uefi-mmap-size", + [DCSIZE] = "linux,uefi-mmap-desc-size", + [DCVERS] = "linux,uefi-mmap-desc-ver", ++ [SBMODE] = "linux,uefi-secure-boot", + } + } + }; +@@ -64,6 +68,11 @@ static int __init efi_get_fdt_prop(const + int len; + u64 val; + ++ if (!pname[0]) { ++ memset(var, 0, size); ++ return 0; ++ } ++ + prop = fdt_getprop(fdt, node, pname, &len); + if (!prop) + return 1; +@@ -81,7 +90,7 @@ static int __init efi_get_fdt_prop(const + return 0; + } + +-u64 __init efi_get_fdt_params(struct efi_memory_map_data *mm) ++u64 __init efi_get_fdt_params(struct efi_memory_map_data *mm, u32 *secure_boot) + { + const void *fdt = initial_boot_params; + unsigned long systab; +@@ -95,6 +104,7 @@ u64 __init efi_get_fdt_params(struct efi + [MMSIZE] = { &mm->size, sizeof(mm->size) }, + [DCSIZE] = { &mm->desc_size, sizeof(mm->desc_size) }, + [DCVERS] = { &mm->desc_version, sizeof(mm->desc_version) }, ++ [SBMODE] = { secure_boot, sizeof(*secure_boot) }, + }; + + BUILD_BUG_ON(ARRAY_SIZE(target) != ARRAY_SIZE(name)); +--- a/drivers/firmware/efi/libstub/fdt.c ++++ b/drivers/firmware/efi/libstub/fdt.c +@@ -132,6 +132,12 @@ static efi_status_t update_fdt(void *ori + } + } + ++ fdt_val32 = cpu_to_fdt32(efi_get_secureboot()); ++ status = fdt_setprop(fdt, node, "linux,uefi-secure-boot", ++ &fdt_val32, sizeof(fdt_val32)); ++ if (status) ++ goto fdt_set_fail; ++ + /* Shrink the FDT back to its minimum size: */ + fdt_pack(fdt); + +--- a/include/linux/efi.h ++++ b/include/linux/efi.h +@@ -764,7 +764,8 @@ extern int efi_mem_desc_lookup(u64 phys_ + extern int __efi_mem_desc_lookup(u64 phys_addr, efi_memory_desc_t *out_md); + extern void efi_mem_reserve(phys_addr_t addr, u64 size); + extern int efi_mem_reserve_persistent(phys_addr_t addr, u64 size); +-extern u64 efi_get_fdt_params(struct efi_memory_map_data *data); ++extern u64 efi_get_fdt_params(struct efi_memory_map_data *data, ++ u32 *secure_boot); + extern struct kobject *efi_kobj; + + extern int efi_reboot_quirk_mode; diff --git a/patches/flatcar-kernel/z0009-block-add-partition-uuid-into-uevent.patch b/patches/flatcar-kernel/z0009-block-add-partition-uuid-into-uevent.patch new file mode 100644 index 00000000..75430910 --- /dev/null +++ b/patches/flatcar-kernel/z0009-block-add-partition-uuid-into-uevent.patch @@ -0,0 +1,36 @@ +From 758737d86f8a2d74c0fa9f8b2523fa7fd1e0d0aa Mon Sep 17 00:00:00 2001 +From: Konstantin Khlebnikov +Date: Fri, 4 Oct 2024 17:13:43 -0700 +Subject: [PATCH] block: add partition uuid into uevent as "PARTUUID" + +Both most common formats have uuid in addition to partition name: +GPT: standard uuid xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx +DOS: 4 byte disk signature and 1 byte partition xxxxxxxx-xx + +Tools from util-linux use the same notation for them. + +Signed-off-by: Konstantin Khlebnikov +Reviewed-by: Kyle Fortin +[dianders: rebased to modern kernels] +Signed-off-by: Douglas Anderson +Signed-off-by: Douglas Anderson +Reviewed-by: Christoph Hellwig +Link: https://lore.kernel.org/r/20241004171340.v2.1.I938c91d10e454e841fdf5d64499a8ae8514dc004@changeid +Signed-off-by: Jens Axboe +--- + block/partitions/core.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/block/partitions/core.c b/block/partitions/core.c +index cdad05f9764768..815ed33caa1b86 100644 +--- a/block/partitions/core.c ++++ b/block/partitions/core.c +@@ -256,6 +256,8 @@ static int part_uevent(const struct device *dev, struct kobj_uevent_env *env) + add_uevent_var(env, "PARTN=%u", bdev_partno(part)); + if (part->bd_meta_info && part->bd_meta_info->volname[0]) + add_uevent_var(env, "PARTNAME=%s", part->bd_meta_info->volname); ++ if (part->bd_meta_info && part->bd_meta_info->uuid[0]) ++ add_uevent_var(env, "PARTUUID=%s", part->bd_meta_info->uuid); + return 0; + } + diff --git a/tests/unit/test_installer_contract.py b/tests/unit/test_installer_contract.py index 66f18fee..74491d0d 100644 --- a/tests/unit/test_installer_contract.py +++ b/tests/unit/test_installer_contract.py @@ -105,7 +105,7 @@ def test_target_initramfs_preloads_sysext_filesystem_drivers() -> None: installer_element = INSTALLER_ELEMENT.read_text(encoding="utf-8") assert ( - '--add-drivers "virtio virtio_blk virtio_pci virtio_scsi nvme nvme_core xfs erofs overlay"' + '--add-drivers "virtio virtio_blk virtio_pci virtio_scsi nvme nvme_core xfs erofs overlay zfs spl"' in installer_element )