'kexec -e' is just a small wrapper that does the xen hypercall
on xen, or otherwise just calls reboot(). Drop the dependency,
and reuse the existing xen hypercall helper.
This is a followup for https://github.com/systemd/systemd/pull/41096
that makes more subsystems pass the new `check-pointer-deref` coccinelle
checks. See the individual commits.
My plan is to do a few more of these PRs until we have it all covered. I
could also do it in a single very big PR but I'm worried about a)
conflicts b) that its just too big/annoying to review. Only 7 dirs left
but some (like src/basic) are quite big (~50k loc) so those PRs will be
a bit bigger.
Align find_ovmf_config() with mkosi's find_ovmf_firmware() by adding
checks that were previously missing:
- Filter on interface-types, only selecting UEFI firmware definitions.
Previously non-UEFI (e.g. BIOS-only) firmware could be selected.
- Check machine type compatibility using substring matching against the
target machine patterns in firmware descriptions (e.g. "q35" matches
"pc-q35-*"), following the same approach as mkosi.
- Make nvram-template optional in the firmware JSON mapping. Firmware
definitions without an nvram-template are now parsed successfully
(with vars remaining NULL) rather than failing entirely.
Also rework the firmware target parsing to store both architecture and
machine arrays per target (instead of just a flat architecture list),
and extract the machine matching into firmware_data_matches_machine().
Co-developed-by: Claude Opus 4.6 <noreply@anthropic.com>
It's useful to be able to check what firmware description vmspawn
will select. In particular, this will allow me to figure out the
nvram template file that will be picked up so I can pick it up in
mkosi and operate on it to pass a modified version of it to vmspawn
with --efi-nvram-template=.
Add --efi-nvram-template=PATH to specify a custom firmware variables
file to copy and use as the initial EFI NVRAM state instead of the
default template from the firmware definition.
Add --firmware-features=FEATURE[,FEATURE...] to require or exclude
specific firmware features during automatic firmware discovery.
Features prefixed with "!" are excluded. If a feature appears in both
the included and excluded lists, inclusion takes priority. Firmware
with the "enrolled-keys" feature is excluded by default.
Refactor --secure-boot= to operate on the firmware features sets
instead of maintaining a separate tristate. --secure-boot=yes adds
"secure-boot" to the include set, --secure-boot=no adds it to the
exclude set, and --secure-boot=auto removes it from both.
Generalize find_ovmf_config() to accept include/exclude feature sets
instead of a secure boot tristate, removing the special-cased
enrolled-keys and secure-boot filtering logic.
Co-developed-by: Claude Opus 4.6 <noreply@anthropic.com>
It's a very common case (vfat...), and it's just too much noise. After
all the whole function exists primarily to deal with O_TMPFILE not being
availeble everywhere...
A malformed image can cause a division by zero, check that
the parameters are not zero.
Reported on yeswehackl.com as YWH-PGM9780-173
Follow-up for 0fa2cac4f0
Our coccinelle/check-pointer-deref.cocci checker has a special
case for `assert(pidref_is_set(param))`. It turns out we can
generalize this and catch the following:
- iovec_is_set
- sd_dhcp_duid_is_set
- sd_dhcp_client_id_is_set
This corrects sorting of menu entries regarding profile numbers:
1. If the profile number is unset, let's treat this identical to profile
0, when ordering stuff, because an item with no profile is
conceptually the same as an item with only a profile 0.
2. Let's take the profile number into account also if sort keys are
used. This was makes profiles work sensibly in type 1 entries, via
the recently added "profile" stanza.
Follow-up for: 5fb90fa319
When showing the list of menu entries via "p", the "internal call:"
field was showing nonsense, since
fb6cf4bbb7.
Fix that by adding a proper entry type for "internal" menu items such as
reboot/firmware/poweroff, and then check for that.
With this in place all entries now have a loader type that makes sense
and describes precisely what an entry is about.
Inspired by the discussion in #41161.
Also change the order of flags to be more logical. First the option
to specify at what fields we look, then the option to specify how we
return their name, the the value, and finally what to do if the value
is missing.
The fix in 8f1751a111 made me wonder if we could automatically detect
when pointers are accessed but when this might not be safe. Systemd
is already using a lot of `assert(dst)` and this change now forces
us to use them.
So this commit (ab)uses coccinelle to flag any pointer parameter
dereference not preceded by assert(param), ASSERT_PTR(param), or an
explicit NULL check. It adds integration into meson as a new "coccinelle"
test suite (just like clang-tidy) and is run in CI. The check is not
perfect but seems a reasonable heuristic.
For this RFC commit it is scoped to a subset, it excludes 25 dirs right
now and includes around 100. About 300 warnings left. Busywork that I am
happy to do if there is agreement that it is worth it.
With this in place we would have caught the bug from 8f1751a111 in CI:
```
FAIL: check-pointer-deref.cocci found issues in systemd/src/boot:
diff -u -p systemd/src/boot/measure.c /tmp/nothing/measure.c
--- systemd/src/boot/measure.c
+++ /tmp/nothing/measure.c
@@ -312,7 +312,6 @@ EFI_STATUS tpm_log_tagged_event(
if (err != EFI_SUCCESS)
return err;
- *ret_measured = true;
return EFI_SUCCESS;
}
```
This also adds a new POINTER_MAY_BE_NULL() for the cases when the
called function will do the NULL check (like `iovec_is_set()`).
This has been requested previously for PCR 7 (#40567), but let's do that
for all firmware owned PCRs, since some firmwares forget to measure
their own separator. Let's hence measure our own guranteed one.
Fixes: #40567
The UKI public key PCR stuff only works if we get PCR measurements from
the pre-boot environment, hence automatically disable the logic by
default if we don't have that.
This is a potentially common case in VMs: firmwares might know the
concept of TPMs, but the hardware is not enabled in the specific VM.
Let's handle this case nicely.
So far we always conditioned our TPM magic on the UKI having detected
TPM support in the firmware. This is a bit limiting when we want to
support a software TPM that is not visible to the firmware. Hence let's
split this up, and add a separate control that can be set via the kernel
command line. However, as before, let's by default inherit the firmare
TPM discovery state into it, to retain the current behaviour unless
overriden.
With this in place, boot with "systemd.tpm2_measured_os=1
systemd.tpm2_software_fallback=1" on the kernel cmdline to get the swtpm
fallback and then a measured OS based on it.
In many cases it's essential to know if the firmware supports a TPM, but
in others we should accept it if the firmware doesn't have TPM support,
in particular if we want to run the OS with a software TPM.
Hence, add tpm2_is_mostly_supported() as function similar to
tpm2_is_fully_supported(), with the only difference that the former
doesn't insist on a firmware supported TPM. Then, change a number of
users over to this (but not all).
We want to start the software TPM fallback only if no real hw is
evailable and if the user opts-in to this behaviour. Add a generator
that drives all this, based on kernel command line configuration.
For TPM-less systems it's sometimes valuable to have a fill-in software
TPM running from early boot on, so that TPM-based functionality can
"just work" and rely on TPM semantics, even if it's at a substantially
weaker security level.
This adds a wrapper around swtpm. It's a binary that chainloads swtpm
but does a few preparatory steps and integrates into systemd's logic
otherwise.
All this is then exposed as systemd-tpm2-swtpm.service.
The service is not hooked into much yet, that is added in later commits.
Before this commit, the > 0 state of arg_newline tristate is
simply ignored.
Yes, this is a minor compat break, but I'd argue the previous
behavior was not useful as "yes" is treated the same as "auto".
An issue also reported that it was quite surprising.
Fixes#41348
The comment about `SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)` is
incorrect. To quote @YHNdnzj:
```
nah, the capability-based permission model is a legacy from kdbus. We cannot do it race-freely without it. Please simply drop the comment.
```
Thanks to @YHNdnzj for suggesting this.
The manager_do_set_objective() was doing a bunch of work to
check the `root` path that can already be done via
`json_dispatch_path` so instead of duplicating use the helper.
Thanks to @YHNdnzj for suggesting this.
Drop the _manager suffix for vl_method_{poweroff,{soft,}reboot,
halt,kexec}_manager.
They're unambiguous enough and the power mgmt operations are
not manager-wide but system-wide.
Thanks to @YHNdnzj for suggesting this.
We need to store state persistently for the software TPM (i.e. the root
key). But given that TPMs are generally used to unlock the rootfs, this
storage cannot be on the rootfs. Hence let's use the ESP instead, as the
next best thing, that is guaranteed to exist during early boot, given we
just were booted from it.
This defines automatic logic for this, but does not cause the ESP mount
job to be enqueued (since typically we don't actually want that
mounted), this is left for the actual services that needs to be done.
Note that the mount here is set up quite differently from the one from
the host: since initrds are short-lived anyway, it seemed pointless to
use autofs. Moreover this uses a fixed place to mount the ESP, inspired
by the /sysroot/ + /sysusr/ mount naming. All that to simplify things a
bit for the consumers (which is mostly swtpm)
This change aligns the behaviour of UKI generation with the behaviour
of BLS. The latter filters out lines starting with a #, allowing users
to add comments and/or temporarily remove some flags from the kernel
command line.
The kernel-install test have been adjusted to use a multiline cmdline
with a comment in it. Without this patch, the test fails.
This adds a new cloud IMDS client, that can cover AWS, Azure, GCP,
Hetzner imds to varying degrees. Each cloud has this and it's very basic
functionality, hence I think it makes sense to add this to systemd.
Since the clouds are all different this tries hard to do the abstract
common logic in code, but encode the endpoint details, and well-known
keys in hwdb, attached to the DMI id device.
Why all this?
* Efficiency: we can schedule this in the initrd, at the earliest points
possible, without unnecessary delays
* Robustness: imds is typically slow and/or heavily rate-limited:
systemd-imdsd as single entrypoint can deal with that, and provide a
reliable, cached interface
* Security: the idea is that systemd-imdsd is the only service behing
able to access the IMDS HTTP, and the host carries a blackhole route for
it otherwise. That way sensitive info can be kept away from clients, and
requires polkit auth for access
* Simplicity: extraction of systemd's system credentials from IMDS
userdata happens with systemd's own infra, and for many usecases that
should already be enough.
* Measurements: before accepting the IDMS userdata, it can be measured
into a PCR, as any other configuration input for the system
Fixes: #40763
A malformed bmp with 8bits depth but smaller color
map would cause out of bounds reads. This is not a real
problem as the image is signed, but better to be safe.
Reported on yeswehack.com as:
YWH-PGM9780-135
Follow-up for 0fa2cac4f0