Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion packages/os/os.spec
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@ Requires: %{_cross_os}metricdog
Requires: %{_cross_os}prairiedog
Requires: %{_cross_os}schnauzer
Requires: %{_cross_os}settings-committer
Requires: %{_cross_os}signpost
Requires: %{_cross_os}storewolf
Requires: %{_cross_os}sundog
Requires: %{_cross_os}xfscli
Expand All @@ -120,6 +119,8 @@ Requires: (%{_cross_os}migration or %{_cross_os}image-feature(no-in-place-update
Requires: (%{_cross_os}thar-be-updates or %{_cross_os}image-feature(no-in-place-updates))
Requires: (%{_cross_os}updog or %{_cross_os}image-feature(no-in-place-updates))

Requires: (%{_cross_os}signpost or %{_cross_os}image-feature(uki-image))

Requires: (%{_cross_os}pluto if %{_cross_os}variant-family(aws-k8s))
Requires: (%{_cross_os}shibaken if %{_cross_os}variant-platform(aws))
Requires: (%{_cross_os}cfsignal if %{_cross_os}variant-platform(aws))
Expand Down Expand Up @@ -239,6 +240,7 @@ Requires: %{_cross_os}nvme-cli

%package -n %{_cross_os}signpost
Summary: Bottlerocket GPT priority querier/switcher
Conflicts: %{_cross_os}image-feature(uki-image)
%description -n %{_cross_os}signpost
%{summary}.
Comment thread
arnaldo2792 marked this conversation as resolved.

Expand Down
6 changes: 6 additions & 0 deletions packages/release/measure-cmdline.service
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ RefuseManualStop=true

[Service]
Type=oneshot
EnvironmentFile=-/usr/share/bottlerocket/image-format.env
Comment thread
arnaldo2792 marked this conversation as resolved.

# Skip on UKI images; the kernel command line is measured as part of the
Comment thread
arnaldo2792 marked this conversation as resolved.
# UKI PE binary itself, not extended separately here.
ExecCondition=[ "${UKI_IMAGE}" != "true" ]

ExecStart=/usr/bin/rottweiler measure kernel-command-line
RemainAfterExit=true

Expand Down
1 change: 1 addition & 0 deletions packages/release/prepare-boot.service
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ DefaultDependencies=no

[Service]
Type=oneshot
EnvironmentFile=-/usr/share/bottlerocket/image-format.env
# We need a helper program to mount the boot partition since it isn't
# trivial to figure out which partition set is active
ExecStart=/usr/bin/prairiedog prepare-boot
Expand Down
5 changes: 4 additions & 1 deletion packages/release/release.spec
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,10 @@ Requires: %{_cross_os}filesystem
Requires: %{_cross_os}findutils
Requires: %{_cross_os}glibc
Requires: %{_cross_os}grep
Requires: %{_cross_os}grub
# For newer versions of twoliter that support UKIs, explicitly request the bootloader(efi) capability
Requires: (%{_cross_os}bootloader(efi) if (%{_cross_os}image-feature(uki-image) or %{_cross_os}image-feature(no-uki-image)))
# Older versions of twoliter that don't support UKIs always get GRUB
Requires: (%{_cross_os}grub or %{_cross_os}image-feature(uki-image) or %{_cross_os}image-feature(no-uki-image))
Comment thread
arnaldo2792 marked this conversation as resolved.
Requires: %{_cross_os}iproute
Requires: %{_cross_os}iptables
Requires: %{_cross_os}kexec-tools
Expand Down
94 changes: 94 additions & 0 deletions packages/systemd-257/9018-do-not-build-32-bit-ia32-sd-boot.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
From 7a35885f3294c0cde362edcb5021556b8906be80 Mon Sep 17 00:00:00 2001
From: Arnaldo Garcia Rincon <agarrcia@amazon.com>
Date: Tue, 4 Aug 2026 03:50:03 +0000
Subject: [PATCH] build: correct sd-boot EFI arch on the Bottlerocket SDK

The SDK cross sysroot mis-reports host_machine.cpu_family(), so systemd's
efi_arch lookup resolves to the wrong EFI target: 'ia32' on x86_64 and 'arm' on
aarch64. Correct both from host_machine.cpu(), and drop the IA-32 mixed-mode
alternate build, which cannot link in this sysroot.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This patch (as well as 9019 and 9020) is missing a Signed-off-by: line


---
meson.build | 38 ++++++++++++++++++++++++++++++--------
src/boot/meson.build | 4 ++--
2 files changed, 32 insertions(+), 10 deletions(-)

diff --git a/meson.build b/meson.build
index b9d8d52..b5e995f 100644
--- a/meson.build
+++ b/meson.build
@@ -1942,6 +1942,36 @@ efi_arch = {
'x86' : 'ia32',
}.get(host_machine.cpu_family(), '')

+# Bottlerocket SDK fix: the cross sysroot reports cpu_family 'x86' even for
+# x86_64 targets, which makes efi_arch resolve to 'ia32'. Force x64 when the
+# real target cpu is x86_64.
+if efi_arch == 'ia32' and host_machine.cpu() == 'x86_64'
+ efi_arch = 'x64'
+endif
+
+# The same SDK quirk applies on 64-bit ARM: cpu_family is reported as 'arm',
+# so efi_arch resolves to the 32-bit 'arm' EFI target and sd-boot is emitted as
+# systemd-bootarm.efi with EFI_MACHINE_TYPE_NAME=arm. Force aa64 when the real
+# target cpu is aarch64, so the binary is named and typed per the EFI spec and
+# matches the bootaa64.efi/grubaa64.efi convention used by shim and GRUB.
+# Note: efi_cpu_family is deliberately left resolving to 'arm' below, since the
+# 'arm' and 'aarch64' entries of efi_arch_c_args are identical
+# (-mgeneral-regs-only) and the extra 'arm' link arg
+# (-Wl,--no-wchar-size-warning) is harmless here.
+if efi_arch == 'arm' and host_machine.cpu() == 'aarch64'
+ efi_arch = 'aa64'
+endif
+
+# Single corrected arch key for all EFI flag lookups, so no flag site can
+# silently regress to the -m32 (ia32) path on this SDK.
+if efi_arch == 'x64'
+ efi_cpu_family = 'x86_64'
+elif efi_arch == 'ia32'
+ efi_cpu_family = 'x86'
+else
+ efi_cpu_family = host_machine.cpu_family()
+endif
Comment on lines +24 to +52

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Overriding efi_arch in systemd's meson.build masks a real SDK bug and is fragile against upstream refactors

The patch works around a Bottlerocket-SDK quirk where host_machine.cpu_family() returns 'x86' on x86_64 and 'arm' on aarch64, and post-processes the value here.

  1. Root cause is elsewhere. host_machine.cpu_family() being wrong is a meson cross-file / SDK configuration bug ([host_machine] cpu_family = 'x86_64' / 'aarch64' are the correct settings). Patching every consumer of cpu_family in systemd is whack-a-mole — the SDK cross-file should be fixed so every build sees the right value. If the SDK fix ever lands, this patch becomes actively misleading.

  2. Incomplete coverage. The patch only replaces host_machine.cpu_family() at two call sites in src/boot/meson.build. Other consumers inside systemd 257 (e.g., arch-specific seccomp lists, syscall filter tables, ukify machinery) will still see the wrong value. The commit message says "no flag site can silently regress" but only sd-boot's efi_archspecs was fixed.

  3. efi_arch_alt sentinel semantics. The patch removes the if have and efi_arch == 'x64' and cc.links(…) block but leaves the efi_arch_alt = '' initializer. Please confirm that efi_archspecs guards the _alt entries with if efi_arch_alt != '' — otherwise meson may still try to build a nameless alt binary.

  4. Aarch64 asserts an unenforced invariant. The comment says "efi_cpu_family is deliberately left resolving to 'arm'" for aarch64, relying on efi_arch_c_args.get('arm', []) == efi_arch_c_args.get('aarch64', []). Any future systemd change that diverges the two entries will silently be lost.

Fix.

  • Preferred: fix the SDK meson cross-file and drop this patch.
  • If the patch must stay: set efi_cpu_family = 'aarch64' explicitly when efi_arch == 'aa64', and add a message()/error() guard that asserts efi_arch_c_args.get('arm') == efi_arch_c_args.get('aarch64') at configure time.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The SDK fix, we can do in a subsequent release. The patch must stay so I'll fix the suggestion.

+
pyelftools = pymod.find_installation('python3',
required : get_option('bootloader'),
modules : ['elftools'])
@@ -1954,14 +1984,8 @@ conf.set_quoted('EFI_MACHINE_TYPE_NAME', have ? efi_arch : '')

efi_arch_alt = ''
efi_cpu_family_alt = ''
-if have and efi_arch == 'x64' and cc.links('''
- #include <limits.h>
- int main(int argc, char *argv[]) {
- return __builtin_popcount(argc - CHAR_MAX);
- }''', args : ['-m32', '-march=i686'], name : '32bit build possible')
- efi_arch_alt = 'ia32'
- efi_cpu_family_alt = 'x86'
-endif
+# IA-32 mixed-mode alternate build disabled for Bottlerocket: the SDK cross
+# sysroot lacks 32-bit glibc headers (gnu/stubs-32.h), so -m32 cannot build.

pefile = pymod.find_installation('python3', required: false, modules : ['pefile'])

diff --git a/src/boot/meson.build b/src/boot/meson.build
index 6327717..28089ef 100644
--- a/src/boot/meson.build
+++ b/src/boot/meson.build
@@ -313,11 +313,11 @@ efi_archspecs = [
'c_args' : [
efi_c_args,
'-DEFI_MACHINE_TYPE_NAME="' + efi_arch + '"',
- efi_arch_c_args.get(host_machine.cpu_family(), []),
+ efi_arch_c_args.get(efi_cpu_family, []),
],
'link_args' : [
efi_c_ld_args,
- efi_arch_c_ld_args.get(host_machine.cpu_family(), []),
+ efi_arch_c_ld_args.get(efi_cpu_family, []),
],
},
]
--
2.52.0

Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
From dd7dfa7106df8f7a0a78d14b3ff494b07eb24025 Mon Sep 17 00:00:00 2001
From: Arnaldo Garcia Rincon <agarrcia@amazon.com>
Date: Wed, 12 Aug 2026 18:55:46 +0000
Subject: [PATCH] boot: remove SMBIOS Type 11 kernel-cmdline-extra mechanism

Remove the ability for sd-boot and the UKI stub to extend the kernel
command line with values read from SMBIOS Type 11 OEM strings
("io.systemd.boot.kernel-cmdline-extra" and
"io.systemd.stub.kernel-cmdline-extra").

SMBIOS Type 11 OEM strings are supplied by the firmware or VMM and
were being trusted to inject additional kernel command line
arguments outside of the UKI/boot entry itself. Remove this
mechanism entirely:

- src/boot/stub.c: drop cmdline_append_and_measure_smbios() and its
call site in run().
- src/boot/boot.c: drop the block in image_start() that appended the
"io.systemd.boot.kernel-cmdline-extra" OEM string to the boot
entry options.
- src/boot/smbios.c, src/boot/smbios.h: drop
smbios_find_oem_string(), which no longer has any callers.

systemd-vmspawn's arg_kernel_cmdline_extra is left untouched: aside
from the (now dead) SMBIOS Type 11 OEM string arguments it still
generates for QEMU when booting via a bootloader/UKI, it is also
used to build the kernel command line passed directly via QEMU's
-append when booting a kernel image directly, so it is not solely
tied to this mechanism.

Documentation under man/ and docs/, and NEWS, are intentionally left
unchanged.
---
src/boot/boot.c | 12 ------------
src/boot/smbios.c | 27 ---------------------------
src/boot/smbios.h | 2 --
src/boot/stub.c | 36 +-----------------------------------
4 files changed, 1 insertion(+), 76 deletions(-)

diff --git a/src/boot/boot.c b/src/boot/boot.c
index 21aa00b356..da5e97771e 100644
--- a/src/boot/boot.c
+++ b/src/boot/boot.c
@@ -23,7 +23,6 @@
#include "sbat.h"
#include "secure-boot.h"
#include "shim.h"
-#include "smbios.h"
#include "ticks.h"
#include "tpm2-pcr.h"
#include "uki.h"
@@ -2599,17 +2598,6 @@ static EFI_STATUS image_start(
* so). */
_cleanup_free_ char16_t *options = xstrdup16(options_initrd ?: entry->options_implied ? NULL : entry->options);

- if (entry->type == LOADER_LINUX && !is_confidential_vm()) {
- const char *extra = smbios_find_oem_string("io.systemd.boot.kernel-cmdline-extra");
- if (extra) {
- _cleanup_free_ char16_t *tmp = TAKE_PTR(options), *extra16 = xstr8_to_16(extra);
- if (isempty(tmp))
- options = TAKE_PTR(extra16);
- else
- options = xasprintf("%ls %ls", tmp, extra16);
- }
- }
-
/* Prefix profile if it's non-zero */
if (entry->profile > 0) {
_cleanup_free_ char16_t *tmp = TAKE_PTR(options);
diff --git a/src/boot/smbios.c b/src/boot/smbios.c
index 329619f85b..844b558cea 100644
--- a/src/boot/smbios.c
+++ b/src/boot/smbios.c
@@ -182,33 +182,6 @@ bool smbios_in_hypervisor(void) {
return FLAGS_SET(type0->bios_characteristics_ext[1], 1 << 4);
}

-const char* smbios_find_oem_string(const char *name) {
- uint64_t left;
-
- assert(name);
-
- const SmbiosTableType11 *type11 = (const SmbiosTableType11 *) get_smbios_table(11, sizeof(SmbiosTableType11), &left);
- if (!type11)
- return NULL;
-
- assert(left >= type11->header.length); /* get_smbios_table() already validated this */
- left -= type11->header.length;
-
- for (const char *p = type11->contents, *limit = type11->contents + left; p < limit; ) {
- const char *e = memchr(p, 0, limit - p);
- if (!e || e == p) /* Double NUL byte means we've reached the end of the OEM strings. */
- break;
-
- const char *eq = startswith8(p, name);
- if (eq && *eq == '=')
- return eq + 1;
-
- p = e + 1;
- }
-
- return NULL;
-}
-
static const char* smbios_get_string(const SmbiosHeader *header, size_t nr, uint64_t left) {
const char *s = (const char *) ASSERT_PTR(header);

diff --git a/src/boot/smbios.h b/src/boot/smbios.h
index 34625c8572..674d702841 100644
--- a/src/boot/smbios.h
+++ b/src/boot/smbios.h
@@ -5,8 +5,6 @@

bool smbios_in_hypervisor(void);

-const char* smbios_find_oem_string(const char *name);
-
typedef struct RawSmbiosInfo {
const char *manufacturer;
const char *product_name;
diff --git a/src/boot/stub.c b/src/boot/stub.c
index 06bf513950..6904d21fd8 100644
--- a/src/boot/stub.c
+++ b/src/boot/stub.c
@@ -17,7 +17,6 @@
#include "sbat.h"
#include "secure-boot.h"
#include "shim.h"
-#include "smbios.h"
#include "splash.h"
#include "tpm2-pcr.h"
#include "uki.h"
@@ -768,37 +767,6 @@ static void measure_sections(
}
}

-static void cmdline_append_and_measure_smbios(char16_t **cmdline, int *parameters_measured) {
- assert(cmdline);
- assert(parameters_measured);
-
- /* SMBIOS OEM Strings data is controlled by the host admin and not covered by the VM attestation, so
- * MUST NOT be trusted when in a confidential VM */
- if (is_confidential_vm())
- return;
-
- const char *extra = smbios_find_oem_string("io.systemd.stub.kernel-cmdline-extra");
- if (!extra)
- return;
-
- _cleanup_free_ char16_t *extra16 = mangle_stub_cmdline(xstr8_to_16(extra));
- if (isempty(extra16))
- return;
-
- /* SMBIOS strings are measured in PCR1, but we also want to measure them in our specific PCR12, as
- * firmware-owned PCRs are very difficult to use as they'll contain unpredictable measurements that
- * are not under control of the machine owner. */
- bool m = false;
- (void) tpm_log_load_options(extra16, &m);
- combine_measured_flag(parameters_measured, m);
-
- _cleanup_free_ char16_t *tmp = TAKE_PTR(*cmdline);
- if (isempty(tmp))
- *cmdline = TAKE_PTR(extra16);
- else
- *cmdline = xasprintf("%ls %ls", tmp, extra16);
-}
-
static void initrds_free(struct iovec (*initrds)[_INITRD_MAX]) {
assert(initrds);

@@ -1219,11 +1187,9 @@ static EFI_STATUS run(EFI_HANDLE image) {
load_all_addons(image, loaded_image, uname, &cmdline_addons, &dt_addons, &n_dt_addons, &initrd_addons, &n_initrd_addons, &ucode_addons, &n_ucode_addons);

/* If we have any extra command line to add via PE addons, load them now and append, and measure the
- * additions together, after the embedded options, but before the smbios ones, so that the order is
- * reversed from "most hardcoded" to "most dynamic". The global addons are loaded first, and the
+ * additions together, after the embedded options. The global addons are loaded first, and the
* image-specific ones later, for the same reason. */
cmdline_append_and_measure_addons(cmdline_addons, &cmdline, &parameters_measured);
- cmdline_append_and_measure_smbios(&cmdline, &parameters_measured);

export_common_variables(loaded_image);
export_stub_variables(loaded_image, profile);
--
2.52.0

Loading
Loading