Commit Graph
140 Commits
Author SHA1 Message Date
Daan De Meyer dbef7bcf29 shared: Followups for #37575 2025-05-25 03:28:50 +09:00
Jelle van der Waa 3f0a9665d9 dissect-image: rename 'dest' -> 'where'
Consistently name dissect_image_mount*.
2025-05-24 16:58:55 +02:00
Daan De Meyer 69a283c5f2 shared: Clean up includes
Split out of #37344.
2025-05-24 14:00:44 +02:00
maia x.andLuca Boccassi dfdeb0b1cb core: reload confexts when reloading notify-reload services
`ExtensionImages=` and `ExtensionDirectories=` now let you specify
vpick-named extensions; however, since they just get set up once when
the service is started, you can't see newer versions without restarting
the service entirely.  Here, also reload confext extensions when you
reload a service. This allows you to deploy a new version of some
configuration and have it picked up at reload time without interruption
to your workload.

Right now, we would only reload confext extensions and leave the sysext
ones behind, since it didn't seem prudent to swap out what is likely
program code at reload. This is made possible by only going for the
`SYSTEMD_CONFEXT_HIERARCHIES` overlays (which only contains `/etc`).

Implementation wise, this uses the new kernel API and two collaborating
child processes under the host & child namespaces in order to gather the
right FDs needed:

  - (1) In child, set up the extension images and directories in a slave
	mountns, and obtain their FDs.
  - (2) Fork into a grandchild under target process namespace, and do a
        "fake" unmount to obtain the FD of the underlying target folder
	say /etc).
  - (3) In the child again, set up new overlay under host NS rights.

We do not want to do I/O heavy jobs inline in PID1 blocking the state
machine, so add separate async states to handle this case.

Co-authored-by: Luca Boccassi <luca.boccassi@gmail.com>
2025-05-19 13:36:21 +01:00
Jelle van der Waa 3e813860c0 shared: use implementation argument naming for dissect_loop_device 2025-05-06 16:26:47 +02:00
Daan De Meyer 8aa304d313 shared: Remove circular dependency between image-policy.h and dissect-image.h
ImagePolicy can just be a forward declaration in dissect-image.h.
2025-04-23 09:53:43 +02:00
Lennart Poettering bcd904d471 dissect-image: move extension release arguments of verity_dissect_and_mount() into a structure 2025-04-03 11:08:57 +02:00
Lennart Poettering f1395724f6 dissect-image: add a concept for "filtering" partitions we dissect
DDIs may contain multiple versions of the same OS, or even multiple
OSes. Hence it makes sense to not just pick the "newest", whatever that
might be, but only partitions associated with specific images, or in a
specific version.

Let's a concept for such filtering: a per-designator glob expression
that can be applied to the partition label string, and can be used for
such filtering.

Usecase: when picking UKI belonging to OS image X in version Y, make
sure we only pick a /usr/ partition belonging to X in version Y, and a
root and home partition belonging to X in any version.

This only adds the basic infrastructure, but doesn't actually expose it
anywhere.
2025-04-03 11:08:57 +02:00
Lennart Poettering e34c89897a dissect-image: guess verity root hash from the resources we found
When dissecting an image, let's make use of the Verity data even if we
got told no root hash explicitly: we can simply determine it by
concatenating the data partition uuid with the verity partition uuid.

Of course, on first thought this doesn't really add much: if the root
hash is not pinned from somewhere, this does not guarantee trust in
the image.

However, this is very useful for attestation: if we have the root hash
we can measure it before mounting things, even if we don't actually
authenticate it.

Hence, at best this helps us with attestation, at worst it doesn't improve
security but certainly doesn't hurt it.
2025-04-03 11:08:57 +02:00
Lennart Poettering a8b2302bc1 udev: add dissect_image builtin
Fixes: #33453 #27897 #18035
2025-04-03 11:08:57 +02:00
Luca Boccassi b7a2f8715e dissect: add helper functions to use VeritySettings in hash/set 2025-02-18 14:44:51 +00:00
Lennart Poettering e57f99305e dissect-image: add client side API wrapper for MountDirectory() varlink call
This is simply a Varlink API client that taks a directory path and
userns fd and returns a mount fd.
2025-01-23 21:48:02 +01:00
Luca Boccassi a1a40297db core: deduplicate identical dm-verity ExtensionImages=
It turns out OverlayFS doesn't handle gracefully when the same source is
specified multiple times in lowerdir= and it fails with ELOOP:

Failed to mount overlay (type overlay) on /run/systemd/mount-rootfs/opt (MS_RDONLY "lowerdir=/run/systemd/unit-extensions/1/opt:/run/systemd/unit-extensions/0/opt:/run/systemd/mount-rootfs/opt"): Too many levels of symbolic links

This happens even if we mount each image in a different internal mount
path, as OverlayFS will resolve it and look for the backing device, which
will be the same device mapper entity, and return a hard error.
This error does not appear if dm-verity is not used, so it is very
confusing for users, and unnecessary.

When mounting ExtensionImages, check if an image is dm-veritied,
and drop duplicates if the root hashes match, to avoid this user-unfriendly
hard error.
2024-06-28 14:37:58 +01:00
Zbigniew Jędrzejewski-Szmek bfd5a0687f various: move const ptr indicator to return value 2024-06-19 16:28:28 +02:00
Lennart Poettering fe7d8235e1 dissect-image: add a generic varlink client side for mountfsd 2024-04-06 16:08:24 +02:00
Lennart Poettering 44e3097dff dissect-image: make dissected_image_acquire_metadata() operate within a userns if possible
This opens the door for making the call work without privileges: if we
pass in a userns fd and DissectedImage that has mount fds then we can
acquire all information without privs.
2024-04-06 16:08:23 +02:00
Lennart Poettering 77740bddbe dissect-image: add a new helper that checks if VeritySettings has anything set at all 2024-04-06 16:08:23 +02:00
Lennart Poettering 9444e54e56 dissect-image: add dissected_image_close() that closes all references to resources 2024-04-06 16:08:23 +02:00
Lennart Poettering f4a63ce25f dissect-image: add flag for explicitly enabling userspace verity signature checking
let's make userspace verity signature checking optional. This adds a
dissection flag to enable the logic and patches through all our users to
enable it by default, thus effectively not changing anything from the
status quo ante. However, know we have a knob to turn this off in
certain scenarios.
2024-02-28 16:17:40 +01:00
Lennart Poettering 2d1e7d1937 dissect-image: introduce new get_common_dissect_directory() helper
So far, if some component mounts a DDI in some local mount namespace we
created a temporary mountpoint in /tmp/ for that. Let's instead use the
same directory inode in /run/ instead. This is safe, since if everything
runs in a local mount namespace (with propagation on /run/ off) then
they shouldn't fight for the inode. And it relieves us from having to
clean up the directory after use. Morever, it allows us to run without
/tmp/ mounted.

This only moves dissect-image.c and the dissec tool over. More stuff is
moved over later.
2024-01-18 01:30:10 +00:00
Lennart Poettering 51778dea0d dissect-image: also store the image size in DissectedImage
That way we can easily access it the same way regardless if we operate
on a block device or on a regular file.
2023-12-13 17:35:22 +01:00
Lennart Poettering 3f8229fbb0 dissect-image: move comment to right place
The image name is extracted from the image path originally passed in,
i.e. not the contents of the image. And the image UUID is directly
retrieved from the partition table, hence also not from the contents.
Let's hence move the comment to separate out the stuff extract from the
file systems (and thus only available when mounting/with privs/with
block devices) from the data available without any of that.
2023-12-12 16:20:10 +01:00
Luca Boccassi 7c83d42ef8 mount-util: use mount beneath to replace previous namespace mount
Instead of mounting over, do an atomic swap using mount beneath, if
available. This way assets can be mounted again and again (e.g.:
updates) without leaking mounts.
2023-10-16 14:33:47 +01:00
Luca Boccassi 0e3986bc1c Merge pull request #29525 from poettering/confext-sysext-multimodal
dissect: make sure we can dissect and inspect DDIs that are both confext *and* sysext
2023-10-14 00:28:47 +01:00
Luca Boccassi 5897469a08 core: fix checking for extension-releases for ExtensionImages/Directories
The parsing is done after the image has been opened, not before, as it
cannot be done on an block device. Also fix returning on any error for
ExtensionDirectories, not just ENOENT.

Follow-up for 55ea4ef096
2023-10-12 12:17:58 +01:00
Lennart Poettering b2466e05c7 dissect: move helpers for categorizing DDIs into generic code
These tests are already done at two places, let's unify them in one
place, and tweak them slightly (specifically: require for considering a
DDI bootable in UEFI we also need need an init system inside).
2023-10-11 15:56:08 +02:00
Lennart Poettering a81fe93e95 dissect: allow confext/sysext to be in the same image
This reworks the image discovery logic, and conceptually allows DDIs
that are both confext and sysext to exist. Previously we'd only extract
one type of exension data from a DDI, with this we allow to extract both
if both exist.

This doesn't add support for true "multi-modal" DDIs, that qualify as
various things at once, it just lays some ground work that ensures we at
least can dissect such images.

This reworks 484d26dac1 quite a bit.

This changes systemd-dissect's JSON output, but given the
version with the fields it changes/dops has never been released (as the
above patch was merged post-v254) this shouldn't be an issue.
2023-10-11 15:56:08 +02:00
Luca Boccassi 3e1072726b dissect-image: support verity_dissect_and_mount() in two steps too
With the new mount API first the image is opened, and later mounted
2023-10-02 14:02:32 +01:00
Lennart Poettering 8d9a1d5979 dissect-image: optionally allow mounting via new kernel mount API in two steps
This adds support for the new fsmount() logic of the kernel: we'll first
create an unattached fsmount fd, and then in a second step attach this
to some real file system inode – as opposed to attaching file system
directly. The benefit of this is that we can pass the open fsmount fds
over some sockets if need be, to isolate the mounting code from the
attaching code.
2023-10-02 14:02:32 +01:00
Maanya Goenka 484d26dac1 confext: add dissect tool support for confext images
Allow image wide systemd tool support for confext images by adding dissect
tool support for these images
2023-07-14 16:59:34 +00:00
Zbigniew Jędrzejewski-Szmek 4953e39c70 gpt-auto-generator: "translate" errno codes into proper messages
E.g. in logs on jammy-ppc64el in https://github.com/systemd/systemd/pull/27294:
Apr 16 17:42:50 H systemd-gpt-auto-generator[300]: Failed to dissect partition table of block device /dev/sda: No message of desired type
Apr 16 17:42:50 H (sd-execu[295]: /usr/lib/systemd/system-generators/systemd-gpt-auto-generator failed with exit status 1.

ee0e6e476e made this particular condition not an
error. But for other errnos we want to print a better message too.
dissect_loop_device_and_warn() already does this, but it always prints the
error at error level. We want to suppress some of the errors, so let's make the
print helper public and do the error suppression in the caller.
2023-04-18 11:58:33 +02:00
Lennart Poettering 598fd4da1c dissect: disallow empty partition tables
If we don't find a single useful partition table, refusing dissection.

(Except in systemd-dissect, when we are supposed to show DDI
information, in that case allow this to run and show general DDI
information, i.e. size, UUID and name at least)
2023-04-05 20:49:48 +02:00
Lennart Poettering 7cd7a19568 dissect: add dissect_image_file_and_warn()
This is to dissect_image_file() what dissect_loop_device_and_warn() is
to dissect_loop_device(), i.e. it dissects the image file and logs an
error string if that fails instead of just returning an error.
2023-04-05 20:47:23 +02:00
Lennart Poettering cd22d8562d dissect: actually enforce policy 2023-04-05 20:46:27 +02:00
Lennart Poettering 84be0c710d tree-wide: hook up image dissection policy logic everywhere 2023-04-05 20:45:30 +02:00
Lennart Poettering 254e392e73 dissect-image: set MS_NOSYMFOLLOW for ESP/XBOOTLDR
When we mount a DDI, let's set MS_NOSYMFOLLOW for ESP/XBOOTLDR. They are
generally untrusted territory, (i.e. outside of
encryption/authentication via dm-crypt/dm-verity). Moreover they are
generally FAT, where symlinks don't exist anyway. Let's hence disable
symlinks for them.

This slightly refactors how we put together mount options for mounts,
splitting this out into a new helper call
dissected_partition_pick_options(), which we should be able to reuse
later in gpt-auto-generator, to ensure mounts via loopback as DDI and
those on bare metal get the same options.
2023-03-09 21:56:42 +01:00
Lennart Poettering c571dee74b dissect: add new helper dissected_partition_fstype()
Initially we only have one user, but following patches will add more.
2023-03-09 16:15:26 +01:00
Lennart Poettering 2348043f17 dissect: show intended architecture of a disk image
We already determine the architecture of disk images and make a choice,
and store it per partition. Let's make this accessible globally.
2023-03-01 17:08:28 +01:00
Daan De Meyer a133d2c366 dissect-image: Return mount point fd if requested 2023-02-17 14:58:55 +01:00
Lennart Poettering 81dde3d85d homework: when creating/resizing GPT partitions, also set sector size explicitly 2023-01-18 10:47:17 +01:00
Lennart Poettering 22ee78a898 loop-util: always tell kernel explicitly about loopback sector size
Let's not leave the sector size unspecified: either set a user supplied
value, or auto-detect the right size by probing the disk image
accordingly.
2023-01-18 10:47:17 +01:00
Lennart Poettering 05c4c59ff1 dissect-image: add probe_sector_size() helper for detecting sector size of a GPT disk image
When we operate with DDIs with sector sizes != 512 we need to configure
the loopback device to match it, otherwise the image and the kernel
block device will disagree what things are.

Let's add a prober that tries to determine the sector size of a GPT DDI.
It does this by looking for the GPT partition table header at the
various byte offsets they must be located on, given a specific sector
size. It will try sector size 512, 1024, 2048 and 4096. Of these only
the 512 and 4096 really make sense IRL I guess, but let's be thorough.
2023-01-18 10:10:57 +01:00
Lennart Poettering 1a81ddef00 dissect-image: optionally, reference dissected partition device nodes by diskseq
This is useful to make the dissection logic at boot a bit safer, as we
can reference device nodes by diskseq.

This locks down dissection a bit, since it makes it harder to swap out
the backing device between the time we dissected and validated it, until
we actually mounted it.

This is not complete though, as /bin/mount would have to verify the
diskseq after opening the diskseq symlink again.

See: https://github.com/util-linux/util-linux/issues/1786
2022-12-23 12:44:57 +01:00
Lennart Poettering 80ce8580f5 dissect-image: let's lock down fstypes a bit
When we dissect images automatically, let's be a bit more conservative
with the file system types we are willing to mount: only mount common
file systems automatically.

Explicit mounts requested by admins should always be OK, but when we do
automatic mounts, let's not permit barely maintained, possibly legacy
file systems.

The list for now covers the four common writable and two common
read-only file systems. Sooner or later we might want to add more to the
list.

Also, it might make sense to eventually make this configurable via the
image dissection policy logic.
2022-12-22 10:30:35 +09:00
Zbigniew Jędrzejewski-Szmek 254d1313ae tree-wide: use -EBADF for fd initialization
-1 was used everywhere, but -EBADF or -EBADFD started being used in various
places. Let's make things consistent in the new style.

Note that there are two candidates:
EBADF 9 Bad file descriptor
EBADFD 77 File descriptor in bad state

Since we're initializating the fd, we're just assigning a value that means
"no fd yet", so it's just a bad file descriptor, and the first errno fits
better. If instead we had a valid file descriptor that became invalid because
of some operation or state change, the other errno would fit better.

In some places, initialization is dropped if unnecessary.
2022-12-19 15:00:57 +01:00
Lennart Poettering c2534821dc dissect: add new helper verity_settings_data_covers()
This function checks if the external verity data referenced in
VeritySettings covers the specified partition (indicated via
designator).

Right now, we'll use that at one place, but in a later commit in more.
2022-12-03 00:22:23 +01:00
Lennart Poettering d90b03f80d dissect: pick up gpt partition flags
Let's store the GPT partition flags in the dissected partition info.

Right now we won't actually use them for anything yet, but later we'll
add that, when enforcing policy on dissection.
2022-12-02 22:52:48 +01:00
Lennart Poettering c80c9079c8 dissect-image: probe file system via main block device fd/image file fd
let's make sure we can probe file systems also when unprivileged:
instead of probing the partition block devices for file system
signatures, let's go via the original "whole" fd.

libblkid makes this easy actually, as it allows us to specify the
offset/size of the area to probe. And we have the partition
offsets/sizes anyway, so it's trivial for us to make use of.

This thus enables fs probing also when lacking privs and operating on
naked regular files without loopback devices or anything like this.
2022-12-01 22:09:30 +01:00
Lennart Poettering 73d88b806b dissect: rework DISSECT_IMAGE_ADD_PARTITION_DEVICES + DISSECT_IMAGE_OPEN_PARTITION_DEVICES
Curently, these two flags were implied by dissect_loop_device(), but
that's not right, because this means systemd-gpt-auto-generator will
dissect the root block device with these flags set and that's not
desirable: the generator should not cause the partition devices to be
created (we don't intend to use them right-away after all, but expect
udev to find/probe them first, and then mount them though .mount units).
And there's no point in opening the partition devices, since we do not
intend to mount them via fds either.

Hence, rework this: instead of implying the flags, specify them
explicitly.

While we are at it, let's also rename the flags to make them more
descriptive:

DISSECT_IMAGE_MANAGE_PARTITION_DEVICES becomes
DISSECT_IMAGE_ADD_PARTITION_DEVICES, since that's really all this does:
add the partition devices via BLKPG.

DISSECT_IMAGE_OPEN_PARTITION_DEVICES becomes
DISSECT_IMAGE_PIN_PARTITION_DEVICES, since we not only open the devices,
but keep the devices open continously (i.e. we "pin" them).

Also, drop the DISSECT_IMAGE_BLOCK_DEVICE combination flag, since it is
misleading, i.e. it suggests it was appropriate to specify on all
dissected blocking devices, but that's precisely not the case, see the
systemd-gpt-auto-generator case. My guess is that the confusion around
this was actually the cause for this bug we are addressing here.

Fixes: #25528
2022-12-01 11:32:30 +01:00
Yu Watanabe 088377e092 dissect-image: do not try to close invalid fd
Fixes a bug introduced by f7725647bb.

Hopefully fixes #25348.
2022-11-13 21:02:53 +01:00