Commit Graph
20 Commits
Author SHA1 Message Date
Kai Lueke 23115eeaf1 sysext: Skip refresh if no changes are found
When the extensions for the final system are already set up from the
initrd we should avoid disrupting the boot process with the remount
(which currently isn't atomic) and the daemon reload for
systemd-confext and systemd-sysext. Similarly, when sysupdate ran and
updated extensions it's best to avoid the remount and daemon reload if
no changes are found.
To do this, encode the current extension state in more detail than
before where only the names of the extensions where encoded in the
overlay mount. This can also be used to provide more details about the
extension origin in "systemd-sysext status (--json=)". During the
refresh add a check whether the old state matches the new state and in
this case skip the refresh unless the user provides a flag to always
refresh. Besides the extension name and the resolved path the best
method for identification is the verity hash but that is not available
for plain image files or directories. Therefore, also include data to
check for file/directory replacements. The creation/modification times
are not always real on reproducible images or extracted archive content.
The file handle together with the unique mount ID is the next best
identifier we can use when we have no verity hash. Fall back to an inode
when we get no handle. With the creation/modification time and the path
this should be good enough. Using a unique mount ID is important (with
a fallback to the regular non-unique mount ID) instead of st_dev because
st_dev gets reused too easily, e.g., by a loop device mount and the
mount ID helps to catch this. For the mount ID to be valid it has to be
resolved before we enter the new mount namespace. Thus, it gets provided
by the image dissect logic and handed over to the sysext subprocess
which runs in a new mount namespace.
Luckily, we can rule out online modification of directories or image
files because this is anyway not well supported with overlay mounts, so
we don't do a file checksum nor do we recurse into a directory to look
for the most recently touched files.  But, as said, with the
always-refresh flag one can force a reload.
2026-02-04 00:05:24 +01:00
Kai Lueke 2e4c2f8df7 sysext: Create mutable directory with the right mode
When the mutable directory didn't exist but gets created with
--mutable=yes then it used to get mode 700 and later it got patched by
a chmod because it is the top layer and must match the target hierarchy.
This meant one could not call the function to resolve the mutable
directory twice before the mount because it has a check for a proper
mode when the directory exists which is the case for the second call.
Also, this resulted in /var/lib/extensions.mutable getting created with
mode 700 which is not really required.

Don't rely on the chmod for the upper dir but directly create the
directory with the right mode by first creating all missing directories
with 755 as a sane default and then changing the mode as needed for the
mutable directory.
2026-02-03 23:55:36 +01:00
Kai Lueke da6d189aa5 test: Add tests for handling symlinks with systemd-sysext
When we now allow following symlinks inside a --root= we should also
test that it works in various cases from simple relative and absolute
symlinks to .v being a symlink itself or its contents, both for
directory and for .raw image extensions. While at it, also add a simple
test for .v without symlinks which wasn't there for direct usage of
systemd-sysext.
2026-01-28 12:24:57 +01:00
Kai Lueke 2ab3a2b44c sysext: Use correct image name for extension release checks
For the extension release check the image name is needed and was derived
from the backing file of the loop device. However, this can have a
different name when symlinks were resolved. The surprising behavior was
that it worked when the target name started with the extension name and
_ because that's what's supported to chop off version suffixes. However,
we should not have such strict requirements for the target name and also
allow - as version separator and entirely different names/prefixes, the
same way as we also do for directories instead of raw images.

Do not use the image name derived from the backing file of the loop
device but directly the extension name we have at hand.
2026-01-28 12:24:57 +01:00
Kai Lueke 5c6bb28999 discover-image: Follow symlinks in a given root
So far systemd-sysext with --root= specified didn't follow extension
symlinks (such as the "current" symlinks managed by systemd-sysupdate).
The main use case is running systemd-sysext --root=/sysroot for setting
up the overlay mounts already from the initrd.

Resolve symlinks correctly but don't defend against later symlink races
that would access a path outside of the given root. Malicous live
modifications are not a realistic threat model and anyway for that one
would need to rework how the image entry is passed over up to the point
when the loop device is set up. This change here does not introduce this
weakness nor does it expose it more than before. Thus, make it explicit
that setting up the extensions for a given --root= implies a certain
trust into this given root tree that it does not try do race conditions
with symlinks to trick systemd-sysext to mount a file outside --root=.
Without a strict --image-policy= set we would anyway mount filesystems
right away which is another attack vector but, again, the main use case
is to do this for the final system which is trusted at this stage.
2026-01-28 12:24:57 +01:00
Kai Lueke fd8a1deb0b sysext: Get verity user certs from given --root=
The verity user certs weren't looked up in the given --root= for
systemd-sysext which made it fail to set up extensions with a strict
image policy.
Look up verity user certs from inside the --root= when we operate on
images in it. The main use case where this matters is when the initrd
sets up the extensions for the final system and thus systemd-sysext
should do the same thing as it would do in the final system.
2026-01-05 06:53:50 +09:00
Kai Lueke 4938777695 man/sysext.conf: Fix section name to match code
The code uses SysExt and ConfExt for section names but the docs use
Sysext and Confext.
Align the docs with the code.
2025-12-12 21:54:47 +09:00
Kai Lueke f351668cbe sysext: Fix config file support with --root=
Config files for --root= weren't picked up as expected because the
--root= flag got parsed after the config file.
Switch the order of config file and CLI flag parsing while letting the
CLI flags overwrite things set by the config files by tracking state
during parsing.
2025-12-12 21:50:45 +09:00
Kai Lueke 570eae5007 sysext: Check for /etc/initrd-release in given --root= tree
Both sysext and confext used the host's /etc/initrd-release file even
when --root=/somewhere was specified. A workaround was the
SYSTEMD_IN_INITRD= env var but without knowing this it was quite
confusing. Aside from users validating their extensions, the primary
use case for this to matter is when the extensions are set up from the
initrd where the initrd-release file is present when running but we want
to prepare the extensions for the final system and thus should match
for the right scope.
Make systemd-sysext check for /etc/initrd-release inside the given
--root= tree. An alternative would be to always ignore the
initrd-release check when --root= is passed but this way it is more
consistent. The image policy logic for EFI-loader-passed extensions
won't take effect when --root= is used, though.
2025-11-04 22:10:50 +09:00
Kai Lueke 6649562924 test: Add missing test cleanup for the last sysext test
The last sysext test leaked things into new tests added later,
uncovered by any new tests leftover check.
Remove the mutable folder state through a trap as done in other tests.
2025-11-04 22:10:18 +09:00
Kai Lueke 88b51ceb56 man: Remove OSConfig project mentioning for systemd-confext
The systemd-confext use case description was mentioning an OSConfig
project which won't say much to users. Also, it's good to call out that
systemd-confext provides a reliable way to manage configuration because
in contrast to other tools it will remove all old configuration files.
2024-05-06 10:54:15 +02:00
Kai Lueke 721412ac98 systemd-sysext/confext.service: Refresh on start/reload
When adding a sysext image to the system and manuall merging it, a
later "systemctl (re)start systemd-sysext" won't work because "merge"
refuses to work when something is merged already. Another problem with
"merge" at start plus "unmerge" at stop is that a service restart can't
make use of the new MOVE_MOUNT_BENEATH in the future even which would
only be available in "refresh". It also prepares us for setting up the
merged overlay for the sysroot from the initrd already, which also
would lead to the mentioned start problem of the service (One
optimization could be to skip the loading but only if we are sure that
all images were loaded and weren't modified since - this assumption is
hard because early services could want to inject a sysext, too).

Use "refresh" on service start to fix the problem that the service
can't start as soon as a manual merge was done. Also add a reload
action that allows to issue "systemctl reload systemd-sysext" and it
will make use of MOVE_MOUNT_BENEATH once we implement this in
systemd-sysext refresh (and it's available from the kernel).
2023-04-06 20:47:26 +09:00
Kai Lueke 1e07c6f31d man/systemd-dissect.xml: Remove old sysext path, add confext path
The /usr/lib/extensions/ location for systemd-sysext images is not
supported anymore. In https://github.com/systemd/systemd/pull/26013
systemd-confext images got introduced and we can list its path under
/usr instead.
2023-04-06 20:46:43 +09:00
Kai Lueke e374439f4b Use original filename for extension name check
The loading of an extension image from a symlink "NAME.raw" to
"NAME-VERSION.raw" failed because the release file name check worked
with the backing file of the loop device which already resolves the
symlink and thus the found name "NAME-VERSION" mismatched "NAME".
Pass the original filename and use it instead of the backing file
when available. This fixes the loading of "NAME.raw" extensions which
are a symlink to "NAME-VERSION.raw" as, e.g., may be the case when
systemd-sysupdate manages multiple versions.

Fixes https://github.com/systemd/systemd/issues/24293
2022-09-06 03:53:03 +09:00
Kai Lueke 1abe15fe9d man: Correct information on sysext masking
While I had tested that a symlink to /dev/null works to "mask" a sysext
I must have gotten something wrong and thus the instructions in
519c2f0d6b don't work. What works,
at least at the moment, is to instead have an empty directory with the
extension name under /etc/extensions/.
Correct the info in the man page and add a test for it.
2022-08-16 20:43:51 +01:00
Kai Lueke 16c1ca0db4 sysext: introduce ARCHITECTURE field to match host architecture
When an extension image has binaries they should match the host
architecture. Currently there is no way to specify this requirement.
Introduce an ARCHITECTURE field in the extension's release file that
may be set to prevent loading on the wrong host architecture.
Since this new field is introduced late, we don't want to make
specifying it mandatory as it would break existing sysext images.

See https://github.com/systemd/systemd/issues/24061
2022-08-15 10:54:32 +02:00
Kai Lueke ab4d43c54e sysext: support distribution-independent extensions using ID=_any
A sysext image that merely contains static binaries has no dependency
on the host distribution and should be able to be used anywhere.
Support the special '_any' value for the ID field in the extension to
opt-out of ID and VERSION_ID/SYSEXT_LEVEL matching.

See https://github.com/systemd/systemd/issues/24061
2022-08-15 10:51:01 +02:00
Kai Lueke 0ad7b7b809 man: Use correct target type for sysupdate entry
While Type=file works because it seems to be the default, the line gets
ignored as printed on the stderr output.
Use the correct value "regular-file" for the target type.
2022-07-22 20:00:08 +01:00
Kai Lueke 519c2f0d6b man: Document mask workaround for sysext images
A read-only /usr may ship a sysext image by default and the user wants
to opt out. Currently it's not clear how to do this.
Document that a /dev/null symlink in /etc/extensions/ works to "mask" a
sysext image in a folder with lower precedence.
2022-07-22 15:09:21 +02:00
Kai Lueke 566e4b3a19 man: Do not recommend to overlay files with sysext even if possible
While overlaying files with a sysext can be useful, it may lead to
unexpected problems depending on when a process got started and which
version of the file it gets.
Call out that overlaying files is possible but don't recommend to make
use of it.
2022-07-22 15:03:12 +02:00