Commit Graph
90486 Commits
Author SHA1 Message Date
Zbigniew Jędrzejewski-Szmek 80c92c896a shared/tpm2-util: use a define instead of a const static variable
Let's do the standard thing. The 'static const' variable requires space
and less efficient code (moving from memory instead of a const insertion).
This doesn't matter much, but let's follow the standard pattern.

Follow-up for 93e9c2c974.
2026-06-25 14:43:42 +02:00
Zbigniew Jędrzejewski-Szmek b14acfdab1 Fix: core fixes (#42744)
Some simple code fixes
2026-06-25 14:39:53 +02:00
Zbigniew Jędrzejewski-Szmek 3498b84013 Couple of hardening changes for utils flagged by kres (#42732) 2026-06-25 14:31:35 +02:00
Paul Meyer e3ebdb8ec5 tpm2: re-manufacture software TPM when state dir is incomplete
setup_swtpm() decided whether a software TPM had already been
manufactured by checking whether the state directory was empty. But
manufacture_swtpm() writes swtpm's config files before forking
swtpm_setup, so an interrupted manufacture leaves the directory
non-empty yet without a usable TPM. The next boot then mistook it for a
complete TPM and started swtpm against a broken state directory.

Keying off a swtpm state file like tpm2-00.permall is no better, as
swtpm_setup gives no guarantee any single one is written atomically or
last. Instead, have manufacture_swtpm() write a marker (.manufactured)
as its very last step, once swtpm_setup has exited successfully, and
gate on it: re-manufacture when it is missing in the initrd, and refuse
rather than start a broken TPM outside it.

Signed-off-by: Paul Meyer <katexochen0@gmail.com>
2026-06-25 13:50:24 +02:00
Paul Meyer abf96165a6 tpm2: write swtpm config files atomically via the state directory fd
Open the swtpm state directory once and write the three config files
relative to that fd with WRITE_STRING_FILE_ATOMIC, rather than by path
with a plain truncating write. Writing atomically ensures a crash or a
concurrent reader never observes a half-written config file, and
operating through a single directory fd lets later steps reuse it.

Signed-off-by: Paul Meyer <katexochen0@gmail.com>
2026-06-25 13:49:42 +02:00
Paul Meyer 47b6a20621 fileio: add write_string_filef_at()
Signed-off-by: Paul Meyer <katexochen0@gmail.com>
2026-06-25 13:33:22 +02:00
Luca Boccassi e4000c0dbf Translations update from Fedora Weblate (#42749)
Translations update from [Fedora
Weblate](https://translate.fedoraproject.org) for
[systemd/main](https://translate.fedoraproject.org/projects/systemd/main/).



Current translation status:

![Weblate translation
status](https://translate.fedoraproject.org/widget/systemd/main/horizontal-auto.svg)
2026-06-25 12:16:52 +01:00
Frantisek Sumsal 14b1a92eb2 unit-name: introduce "strict" mode for unit name mangling
unit_name_mangle_with_suffix() is quite benevolent by default and allows
the unit to "transition" into a different unit type than what's
requested via its suffix argument. For example, calling
unit_name_mangle_with_suffix() with "/foo/bar" as a unit name and
".service" as a suffix would give you "foo-bar.mount", without any
warning or error.

This could then lead to a quite confusing errors in certain situations:

~# systemd-run --remain-after-exit --unit /foo/bar true
Failed to start transient service unit: Cannot set property RemainAfterExit, or unknown property.

Given we can't change the default behaviour of
unit_name_mangle_with_suffix() as some parts of systemd already depend
on its "benevolence" (like systemctl), let's introduce a new flag -
UNIT_NAME_MANGLE_STRICT - that checks if the mangled/resolved unit
name's suffix matches the requested one and errors out if not.

With the flag used throughout systemd-run's code, the error in the above
case is now a bit more clear:

~# build/systemd-run --remain-after-exit --unit /foo/bar true
Path "/foo/bar" resolves to unit type "mount", but "service" is expected as unit.
Failed to mangle unit name: Invalid argument

Resolves: #39996
2026-06-25 12:58:06 +02:00
Fco. Javier F. Serrador a0a57873bd po: Translated using Weblate (Spanish)
Currently translated at 100.0% (286 of 286 strings)

Co-authored-by: Fco. Javier F. Serrador <fserrador@gmail.com>
Translate-URL: https://translate.fedoraproject.org/projects/systemd/main/es/
Translation: systemd/main
2026-06-25 12:17:55 +02:00
Weblate Translation Memory 11160d967f po: Translated using Weblate (Romanian)
Currently translated at 89.5% (256 of 286 strings)

Co-authored-by: Weblate Translation Memory <noreply-mt-weblate-translation-memory@weblate.org>
Translate-URL: https://translate.fedoraproject.org/projects/systemd/main/ro/
Translation: systemd/main
2026-06-25 12:17:55 +02:00
Petru Rebeja 77f7c7ef8c po: Translated using Weblate (Romanian)
Currently translated at 89.5% (256 of 286 strings)

Co-authored-by: Petru Rebeja <petru@rebeja.eu>
Translate-URL: https://translate.fedoraproject.org/projects/systemd/main/ro/
Translation: systemd/main
2026-06-25 12:17:55 +02:00
Luca Boccassi 364bc151db machined: allow privileged users to register other users machines (#39042)
Requires https://github.com/polkit-org/polkit/pull/591
2026-06-25 10:53:04 +01:00
Luca Boccassi 6815a48f08 machined: allow privileged users to register other users machines
If a user is authenticated by polkit as admin then it should be
able to manage any resource on the system.

Follow-up for 119d332d9c
2026-06-25 10:39:11 +01:00
Luca Boccassi 5ce1786227 polkit: check if user authenticated as admin
The new polkit will return a new detail regarding a successful
authentication: the actual result type, which we can use to
see whether the user authenticated as admin. This can be used
to grant additional privileges.
2026-06-25 10:39:11 +01:00
Paul Meyer 087b0ebb61 units: harden systemd-report-sign-plain@.service
Apply sandboxing. The plain backend's needs writable StateDirectory and
/dev/urandom for key generation. The service must stay root (the
private key is root-only), but everything else is locked down.

Signed-off-by: Paul Meyer <katexochen0@gmail.com>
2026-06-25 10:33:01 +01:00
Syed Mohammed Nayyar 15bee24d4f journald: bound field length in extra-fields reader
client_context_read_extra_fields() reads a 64-bit field length v from
the per-unit log-extra-fields file. n = sizeof(uint64_t) + v overflows
when v is near UINT64_MAX, so the "left < n" check is bypassed and the
following memchr() scans v bytes past the buffer. Bound v against the
remaining bytes instead, which cannot overflow.
2026-06-25 10:32:20 +01:00
Frantisek Sumsal 89f1f76624 unit-name: use FLAGS_SET() more 2026-06-25 11:31:28 +02:00
Luca BoccassiandPaul Meyer d30e87ea49 uid-range: fix out-of-bounds write in uid_range_partition()
uid_range_partition() filled the grown entries[] buffer backwards in
place. The backward-fill invariant (the write cursor stays above the
read index) only holds when every source entry contributes at least
one partition; an entry with nr < size contributes zero, so the cursor
stalls while the read index keeps descending. A later multi-part
entry's writes then overwrite the still-live zero-part slot, the
corrupted slot is re-read as a one-part entry, and the next
range->entries[--t] underflows.

Add a forward compaction first pass that drops the zero-part entries
before the backward fill.

Follow-up for 025439faaa

Co-Authored-by: Paul Meyer <katexochen0@gmail.com>
2026-06-25 10:28:54 +01:00
Zbigniew Jędrzejewski-Szmek a0343dabfa core: derive restrict-fsaccess initramfs_s_dev offset from skeleton (#42705)
Fixes #42689.
2026-06-25 11:24:28 +02:00
Luca Boccassi f98629421b dhcp6: reject IA_PD_PREFIX with invalid prefix length
dhcp6_option_parse_ia_pdprefix() validates the lifetimes but never the
prefixlen byte, so a delegated prefix with prefixlen == 0 or > 128 is
stored in the lease and handed over.

RFC 8415 defines the prefix length as 1 to 128, and the send-side
option_append_pd_prefix() already rejects 0, so reject the out-of-range
values on the receive path too.

Follow-up for f8ad4dd45d
2026-06-25 10:16:26 +01:00
Luca Boccassi a762c92a7c sd-lldp-rx: keep object ref around event callbacks
If the user callback set via sd_lldp_rx_set_callback() drops the last
reference to the sd_lldp_rx object, trying to use it later does not go
well. Take a ref to keep the objects alive as long as they are needed.
2026-06-25 10:16:26 +01:00
dongshengyuan 68b59ca74f systemctl: fix continue placement in clean-or-freeze error handling
When sd_bus_call() fails, the continue was inside the
'if (ret == EXIT_SUCCESS)' guard, so only the first failure skipped
adding the unit to the job waiter. On the second and subsequent
failures, the unit was still passed to bus_wait_for_units_add_unit()
despite no job being started, causing bus_wait_for_units_run() to
hang indefinitely.

Move continue outside the guard so any failure skips the waiter
registration. The guard still prevents ret from being overwritten by
a later error code.

Signed-off-by: dongshengyuan <dongshengyuan@uniontech.com>
2026-06-25 16:40:28 +08:00
Michael Vogt bc4dfc24a5 basic: add assert() when doing pointer deref
Lennart reminded me in [1] that we need to add assert() in functions
that do pointer access. For the simple `*p` pointer dereferences
we even have an automatic coccinelle script that ensures that as
part of the automatic code checks.

However for deref in the `p->` style this is not supported right
now and adding it to coccinelle is hard because its too slow for
this kind of check. So I created a (slightly messy) tree-sitter
python script to see how many asserts we are currently missing.

This commit is the result of running it over the `src/basic`
dir and fixing the flagged issues. I plan to tidy it up and
add it to the checks too but this is orthogonal to this commit.

[1] https://github.com/systemd/systemd/pull/42360#discussion_r3426964562
2026-06-25 10:40:21 +02:00
dongshengyuan 3daf3e19da core: fix fd leak in exec_shared_runtime_deserialize_one
The userns/netns/ipcns fdpairs were declared as plain int arrays without
_cleanup_close_pair_. If exec_shared_runtime_add() fails (e.g. OOM on
hashmap_ensure_put), the already-opened fds are leaked.

Since exec_shared_runtime_add() uses TAKE_FD on success, the array
entries are reset to -1 after ownership transfer, so adding
_cleanup_close_pair_ is safe and closes the fds only when they were
never consumed.

Signed-off-by: dongshengyuan <dongshengyuan@uniontech.com>
2026-06-25 16:40:05 +08:00
Lennart Poettering cd346b8ba7 Assorted coverity fixes (#42738)
Coverity is back online, and it's not happy
2026-06-25 10:29:57 +02:00
dongshengyuan 32165a1a48 network: roll back ipv6ll_address on link_ipv6ll_gained() failure
If link_ipv6ll_gained() fails after ipv6ll_address is set, the address
remains non-null and the null-guard in address_update() never triggers
again, permanently suppressing SLAAC, DHCPv6 and RA on that link.

Clear ipv6ll_address on the failure path so the guard can fire when
the address is re-announced.

Signed-off-by: dongshengyuan <dongshengyuan@uniontech.com>
2026-06-25 16:19:14 +08:00
dongshengyuan da0252110c sysupdate: propagate transfer_instance_vacuum() errors
Both vacuum loops silently return 0 on failure instead of propagating
the error code, hiding disk cleanup failures from the caller.

Signed-off-by: dongshengyuan <dongshengyuan@uniontech.com>
2026-06-25 16:16:40 +08:00
dongshengyuan a9e8f89592 sd-journal: fix memzero size in data hash table setup
journal_file_setup_data_hash_table() allocates s * sizeof(HashItem)
bytes for the hash table but then only zeroes s bytes, leaving 15/16 of
the entries uninitialized. This corrupts the hash chain in any newly
created journal file.

The adjacent journal_file_setup_field_hash_table() already uses the
correct size.

Signed-off-by: dongshengyuan <dongshengyuan@uniontech.com>
2026-06-25 16:04:54 +08:00
Paul Meyer 2f1c3b8afb units: harden systemd-tpm2-swtpm.service
Lock down the software TPM service: restrict the runtime directory (which
holds the AES key sealing swtpm's state) to 0700, and apply the usual
sandboxing (NoNewPrivileges, MemoryDenyWriteExecute, ProtectSystem-adjacent
Protect*/Restrict* knobs, PrivateNetwork, PrivateTmp, a @system-service
syscall filter, etc.).

A few common knobs can't be used here: the service must keep CAP_SYS_ADMIN
(needed for the ioctl that creates the vtpm proxy device on /dev/vtpmx),
and it needs runtime access to the ESP and its backing block device at a
path only known at runtime, which rules out PrivateDevices=, DevicePolicy=,
ProtectSystem= and User=/DynamicUser=.

Signed-off-by: Paul Meyer <katexochen0@gmail.com>
2026-06-25 09:39:55 +02:00
Paul Meyer df2baac2b9 tpm2: stop the software TPM before the ESP is unmounted on shutdown
swtpm keeps its state on the ESP (--tpmstate=dir=) and thus holds it
busy for as long as it runs, but nothing ensured it was stopped before
the ESP was unmounted on shutdown, leaving boot.mount failing to
unmount.

Two things were missing:

- systemd-tpm2-swtpm.service has DefaultDependencies=no, which strips
  the implicit shutdown.target membership, so it was torn down late
  rather than stopped in an ordered manner. Add
  Conflicts=/Before=shutdown.target, as the sibling
  systemd-tpm2-setup{,-early}.service units already do.

- The generator only ordered the service
  After=boot.automount/efi.automount. Ordering after the .automount
  units is enough for start-up, but only an ordering against the actual
  .mount units makes the service stop (releasing the ESP) before the
  file system is unmounted. Add boot.mount/efi.mount to the After= line;
  this is a no-op at start-up, as the mount has no job of its own there
  (it is triggered on access via the automount).

Signed-off-by: Paul Meyer <katexochen0@gmail.com>
2026-06-25 09:39:55 +02:00
Paul Meyer 1b1900a6f3 test: add TEST-92-TPM2-SWTPM for the software TPM fallback
Boot a VM in EFI mode without a hardware/firmware TPM and with
systemd.tpm2_software_fallback=yes, so systemd-tpm2-generator manufactures a
software TPM on the ESP in the initrd and chainloads swtpm. Assert the service
starts, the vtpm-proxy device shows up, and a systemd-creds TPM2 seal/unseal
round-trip works. Then reboot and confirm the sealed secret still unseals,
i.e. the TPM state persisted on the ESP across the reboot.

Signed-off-by: Paul Meyer <katexochen0@gmail.com>
2026-06-25 09:39:55 +02:00
Luca Boccassi 45033e39ec sd-future: drop redundant branch in test reader fiber
Both the error and the success path returned (int) n, so the check was
a no-op. Return the value directly.

CID#1660095

Follow-up for 7bc793e21f
2026-06-24 19:09:36 +01:00
Luca Boccassi 6ebf344a1b core: actually sort the parsed LUO session list
The strv_sort() call sat after a for (;;) loop whose only exits are
return statements inside the loop, so it never ran.

CID#1660125

Follow-up for 82b8615463
2026-06-24 19:08:41 +01:00
Luca Boccassi 2e79d397a4 dhcp-message-dump: guard against negative option type before indexing
dhcp_option_type_from_code() returns _DHCP_OPTION_TYPE_INVALID (-EINVAL)
for the PAD and END option codes, and dump_dhcp_option_one() uses the
returned value directly as an index into the functions[] table. Those
codes are excluded by an assert() at the top of the function, but
assert() compiles down to __builtin_unreachable() under NDEBUG, so a
negative array index read is reachable there (and trips static
analyzers). Bail out explicitly on the error return.

CID#1660105

Follow-up for 149adb2fdc
2026-06-24 19:06:21 +01:00
Luca Boccassi 1f9d56a7ab hostname-setup: avoid O(N^2) string building in wildcard substitution
Building the result one char at a time via strextendn() is O(N^2)
because each call rescans and reallocs the buffer. With lines up to
LONG_LINE_MAX this caused a timeout in fuzz-hostname-setup. Use
GREEDY_REALLOC_APPEND to make it linear.

Fixes https://github.com/systemd/systemd/issues/42713
2026-06-24 18:49:25 +01:00
Luca Boccassi a6e2bfe533 resolved: fix potential use-after-free when freeing DNS extra stub listeners
dns_stub_listener_extra_free() frees the listener while DnsQuery and
DnsStream objects still keep pointers to it. On a reload the extra
listeners are freed before dns_stream_disconnect_all() and
dns_query_free() run, and dns_query_free() then dereferences those
pointers.
2026-06-24 18:02:12 +01:00
Luca Boccassi 218ac81f85 resolved: avoid dangling hashmap entry on RegisterService failure
bus_method_register_service() inserted the DnssdRegisteredService into
m->dnssd_registered_services before assigning service->manager and
before the sd_bus_track_new()/sd_bus_track_add_sender() calls, so if
either failed, the destructor ran with service->manager still NULL,
so its guarded hashmap_remove() was skipped and the freed service was
left in the hashmap.
2026-06-24 18:02:12 +01:00
Lennart Poettering 84f6da603e sysupdate: do a varlink callout to a ready when completing an update, and hook bootctl install, pcrlock and sysext refresh into it (#42365) 2026-06-24 16:58:45 +02:00
LucasTavaresA b48228a559 hwdb: map Brazilian ThinkPad T14 Gen 1 slash key to KEY_RO
On Lenovo ThinkPad T14 Gen 1 AMD model 20UES5TQ00 with the Brazilian
keyboard, the physical slash/question key reports as KEY_RIGHTCTRL.

This keyboard layout has no physical Right Ctrl key in that position. The
key after Space is AltGr, then PrtSc, then the slash/question key. Map the
AT keyboard scancode 0x9d to KEY_RO, matching the ABNT slash/question key
used by Brazilian keyboard layouts.

Verified with evtest:

Event: type 4 (EV_MSC), code 4 (MSC_SCAN), value 9d
Event: type 1 (EV_KEY), code 97 (KEY_RIGHTCTRL), value 1

After applying the hwdb mapping, the key reports as KEY_RO.

DMI: svnLENOVO:pn20UES5TQ00:pvrThinkPadT14Gen1
AT keyboard scancode: 0x9d
2026-06-24 15:37:27 +01:00
Luca Boccassi f66144cf2a string-util: check for short input in previous_ansi_sequence()
ellipsize_mem() scans backwards for ANSI escape sequences and calls
previous_ansi_sequence(s, t - s, ...) as t walks down toward s. When
t reaches s + 1 the helper is invoked with length == 1 and computes
'length - 2', which wraps to SIZE_MAX - 1.

Follow-up for cb558ab222
2026-06-24 14:48:04 +01:00
Lennart Poettering 01f3f2aa2f TODO: drop bootctl link + sysupdate integration item
This is now implemented: sysupdate calls out to the
/run/systemd/sysupdate/notify/ Varlink directory on completion, and bootctl
binds a socket there that links a UKI plus extras staged below
/var/lib/systemd/uki/ (with .v/ vpick support) via "bootctl link-auto".
2026-06-24 13:06:20 +02:00
Lennart Poettering 9ac1b6c124 test: verify bootctl link-auto and io.systemd.BootControl.LinkAuto
Add a TEST-87 testcase exercising "bootctl link-auto" and the equivalent
io.systemd.BootControl.LinkAuto() Varlink method: a UKI plus extras are staged
below the search directories and we assert the kernel and sidecar resources
are linked into $BOOT. Covered: plain kernel.efi + extras.d/, versioned
kernel.efi.v/ and extras .v/ resolved via vpick, directory priority
(/etc wins over /run), the no-op case when nothing is staged, and the Varlink
method including its empty reply when there is nothing to link.
2026-06-24 13:06:20 +02:00
Lennart Poettering 89dd06505b test: verify sysupdate invokes the notification callout directory
Extend TEST-72-SYSUPDATE with a check that, after a successful update,
systemd-sysupdate connects to every socket linked into
/run/systemd/sysupdate/notify/ and invokes
io.systemd.SysUpdate.Notify.OnCompletedUpdate(). A tiny recorder socket is
hooked into that directory; it captures the request and replies with success.
We assert the recorded call carries the expected method, version and resource
list, and that a subsequent no-op update emits no notification.
2026-06-24 13:06:19 +02:00
Lennart Poettering be1643b549 systemd-boot-update: condition on UEFI
Our boot loader logic only supports UEFI, hence let's condition the
updater on it.
2026-06-24 13:05:34 +02:00
Lennart Poettering 942283288d sysext: refresh sysexts and confexts on completed system update
Bind the io.systemd.SysUpdate.Notify.OnCompletedUpdate() method in the
sysext Varlink server. systemd-sysext provides a single Varlink service
covering both the sysext and confext image classes, so one notification
refreshes both (equivalent to "systemd-sysext refresh" plus
"systemd-confext refresh"). Hook a socket into
/run/systemd/sysupdate/notify/ via systemd-sysupdate-notify-sysext.socket,
enabled by default via the preset.
2026-06-24 13:05:34 +02:00
Lennart Poettering 1421e6c5f4 bootctl: add link-auto/LinkAuto and auto-link on completed system update
Add a "bootctl link-auto" verb and a matching io.systemd.BootControl.LinkAuto()
Varlink method that behave exactly like "bootctl link" / Link(), except that
the UKI and extra resources are discovered automatically instead of being
passed in. The following directories are searched, in decreasing priority:
/etc/systemd/uki/, /run/systemd/uki/, /var/lib/systemd/uki/ (where
systemd-sysupdate stages downloaded resources), /usr/local/lib/systemd/uki/
and /usr/lib/systemd/uki/.

  - the UKI is taken from kernel.efi, or the best version in kernel.efi.v/
    (resolved via vpick, without honouring boot-counting suffixes), from the
    highest-priority directory that has one;
  - extra resources are picked up from extras.d/, matching *.sysext.raw,
    *.confext.raw and *.cred, each either as a plain file or as a versioned
    *.v/ directory resolved via vpick, combined across all directories with
    higher-priority directories winning on conflicts.

Everything is resolved relative to the pinned root directory fd. Files passed
via --extra= on the command line are linked in addition to the auto-discovered
ones.

Also bind io.systemd.SysUpdate.Notify.OnCompletedUpdate() in the boot control
Varlink server, which simply does the same as LinkAuto(), and hook a socket
into /run/systemd/sysupdate/notify/ via systemd-sysupdate-notify-bootctl.socket
(enabled by default via the preset) so a freshly downloaded kernel is linked
into $BOOT automatically after a sysupdate run.
2026-06-24 13:05:34 +02:00
Lennart Poettering 27b7fb9b20 pcrlock: recompute PCR policy on completed system update
Bind the io.systemd.SysUpdate.Notify.OnCompletedUpdate() method in the
pcrlock Varlink server and hook a socket into
/run/systemd/sysupdate/notify/ via systemd-sysupdate-notify-pcrlock.socket,
enabled by default via the preset. When sysupdate signals a completed
update, we unconditionally re-run make-policy, since the set of measured
components may have changed.
2026-06-24 13:05:34 +02:00
Lennart Poettering d36bdc9467 sysupdate: notify hook subscribers after a successful update
Define a new io.systemd.SysUpdate.Notify Varlink interface with a single
OnCompletedUpdate() method, and after sysupdate successfully installs an
update, invoke that method on every socket linked into
/run/systemd/sysupdate/notify/ via varlink_execute_directory(). This
gives other components a hook to react to applied updates (e.g. recompute
a TPM policy, link a freshly downloaded kernel, refresh extensions).

The notification carries the component name, the installed version and the
list of updated resources (transfer id + on-disk path). Subscribers are
free to ignore the parameters and just treat the call as a trigger.

Setting SYSTEMD_SYSUPDATE_FORCE_NOTIFY=1 forces the notification to be sent
even when no update was applied (in which case no resource list is included),
so follow-up work can be triggered unconditionally.

Fixes: #35988
2026-06-24 13:05:33 +02:00
Lennart Poettering 95a372a514 vpick: take separate root_fd and dir_fd arguments
Mirror how chaseat() works these days: instead of a single toplevel_fd that
serves as both the root (chroot) boundary and the directory that resolution
starts from, path_pick() now takes a separate root_fd and dir_fd. This lets
callers resolve a path relative to a specific directory fd while confining
symlink and absolute-path resolution to a root directory fd.

All existing callers are updated to pass the same fd for both, preserving
their current behaviour.
2026-06-24 12:59:55 +02:00
Paul Meyer 236bade19c man: document SEV-SNP credential delivery via initrd cpio
Under --coco=sev-snp, credentials no longer flow through SMBIOS/fw_cfg
(which the guest PID1 discards as unmeasured in confidential VMs) but
through a cpio archive appended to the initrd, landing in the @system
bucket via the new /.extra/system_credentials/ initrd path. Update
systemd-vmspawn(1) to describe this and the guest systemd version
requirement.

Signed-off-by: Paul Meyer <katexochen0@gmail.com>
2026-06-24 12:47:42 +02:00