From f4a63ce25f1b672fa2e5b52462ac925bb0027291 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 28 Feb 2024 13:17:03 +0100 Subject: [PATCH] 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. --- src/analyze/analyze.c | 3 +- src/boot/bootctl.c | 3 +- src/core/namespace.c | 3 +- src/coredump/coredumpctl.c | 3 +- src/dissect/dissect.c | 3 +- src/firstboot/firstboot.c | 3 +- src/journal/journalctl.c | 3 +- src/kernel-install/kernel-install.c | 3 +- src/machine-id-setup/machine-id-setup-main.c | 3 +- src/nspawn/nspawn.c | 16 +++++--- src/partition/repart.c | 3 +- src/portable/portable.c | 39 ++++++++++++-------- src/shared/discover-image.c | 33 +++++++++++------ src/shared/dissect-image.c | 21 ++++++++--- src/shared/dissect-image.h | 1 + src/shared/mount-util.c | 4 +- src/sysext/sysext.c | 3 +- src/systemctl/systemctl.c | 3 +- src/sysupdate/sysupdate.c | 3 +- src/sysusers/sysusers.c | 3 +- src/tmpfiles/tmpfiles.c | 3 +- 21 files changed, 103 insertions(+), 56 deletions(-) diff --git a/src/analyze/analyze.c b/src/analyze/analyze.c index ea906c7bfeb..b449e538f31 100644 --- a/src/analyze/analyze.c +++ b/src/analyze/analyze.c @@ -681,7 +681,8 @@ static int run(int argc, char *argv[]) { arg_image_policy, DISSECT_IMAGE_GENERIC_ROOT | DISSECT_IMAGE_RELAX_VAR_CHECK | - DISSECT_IMAGE_READ_ONLY, + DISSECT_IMAGE_READ_ONLY | + DISSECT_IMAGE_ALLOW_USERSPACE_VERITY, &mounted_dir, /* ret_dir_fd= */ NULL, &loop_device); diff --git a/src/boot/bootctl.c b/src/boot/bootctl.c index bd10c08b82e..b883159dcf1 100644 --- a/src/boot/bootctl.c +++ b/src/boot/bootctl.c @@ -537,7 +537,8 @@ static int run(int argc, char *argv[]) { arg_image, arg_image_policy, DISSECT_IMAGE_GENERIC_ROOT | - DISSECT_IMAGE_RELAX_VAR_CHECK, + DISSECT_IMAGE_RELAX_VAR_CHECK | + DISSECT_IMAGE_ALLOW_USERSPACE_VERITY, &mounted_dir, /* ret_dir_fd= */ NULL, &loop_device); diff --git a/src/core/namespace.c b/src/core/namespace.c index e55982ffa5b..855ad0de893 100644 --- a/src/core/namespace.c +++ b/src/core/namespace.c @@ -2125,7 +2125,8 @@ int setup_namespace(const NamespaceParameters *p, char **error_path) { DISSECT_IMAGE_USR_NO_ROOT | DISSECT_IMAGE_GROWFS | DISSECT_IMAGE_ADD_PARTITION_DEVICES | - DISSECT_IMAGE_PIN_PARTITION_DEVICES; + DISSECT_IMAGE_PIN_PARTITION_DEVICES | + DISSECT_IMAGE_ALLOW_USERSPACE_VERITY; int r; assert(p); diff --git a/src/coredump/coredumpctl.c b/src/coredump/coredumpctl.c index 53769f8d4c6..52ded50776c 100644 --- a/src/coredump/coredumpctl.c +++ b/src/coredump/coredumpctl.c @@ -1394,7 +1394,8 @@ static int run(int argc, char *argv[]) { DISSECT_IMAGE_GENERIC_ROOT | DISSECT_IMAGE_REQUIRE_ROOT | DISSECT_IMAGE_RELAX_VAR_CHECK | - DISSECT_IMAGE_VALIDATE_OS, + DISSECT_IMAGE_VALIDATE_OS | + DISSECT_IMAGE_ALLOW_USERSPACE_VERITY, &mounted_dir, /* ret_dir_fd= */ NULL, &loop_device); diff --git a/src/dissect/dissect.c b/src/dissect/dissect.c index 27669902969..bef75289777 100644 --- a/src/dissect/dissect.c +++ b/src/dissect/dissect.c @@ -79,7 +79,8 @@ static DissectImageFlags arg_flags = DISSECT_IMAGE_USR_NO_ROOT | DISSECT_IMAGE_GROWFS | DISSECT_IMAGE_PIN_PARTITION_DEVICES | - DISSECT_IMAGE_ADD_PARTITION_DEVICES; + DISSECT_IMAGE_ADD_PARTITION_DEVICES | + DISSECT_IMAGE_ALLOW_USERSPACE_VERITY; static VeritySettings arg_verity_settings = VERITY_SETTINGS_DEFAULT; static JsonFormatFlags arg_json_format_flags = JSON_FORMAT_OFF; static PagerFlags arg_pager_flags = 0; diff --git a/src/firstboot/firstboot.c b/src/firstboot/firstboot.c index d9d2e282519..7f6c1461209 100644 --- a/src/firstboot/firstboot.c +++ b/src/firstboot/firstboot.c @@ -1694,7 +1694,8 @@ static int run(int argc, char *argv[]) { DISSECT_IMAGE_VALIDATE_OS | DISSECT_IMAGE_RELAX_VAR_CHECK | DISSECT_IMAGE_FSCK | - DISSECT_IMAGE_GROWFS, + DISSECT_IMAGE_GROWFS | + DISSECT_IMAGE_ALLOW_USERSPACE_VERITY, &mounted_dir, &rfd, &loop_device); diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 6262dd0aa6b..6f83585db5f 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -2326,7 +2326,8 @@ static int run(int argc, char *argv[]) { DISSECT_IMAGE_REQUIRE_ROOT | DISSECT_IMAGE_VALIDATE_OS | DISSECT_IMAGE_RELAX_VAR_CHECK | - (arg_action == ACTION_UPDATE_CATALOG ? DISSECT_IMAGE_FSCK|DISSECT_IMAGE_GROWFS : DISSECT_IMAGE_READ_ONLY), + (arg_action == ACTION_UPDATE_CATALOG ? DISSECT_IMAGE_FSCK|DISSECT_IMAGE_GROWFS : DISSECT_IMAGE_READ_ONLY) | + DISSECT_IMAGE_ALLOW_USERSPACE_VERITY, &mounted_dir, /* ret_dir_fd= */ NULL, &loop_device); diff --git a/src/kernel-install/kernel-install.c b/src/kernel-install/kernel-install.c index 2523d439449..273c1d9c472 100644 --- a/src/kernel-install/kernel-install.c +++ b/src/kernel-install/kernel-install.c @@ -1699,7 +1699,8 @@ static int run(int argc, char* argv[]) { DISSECT_IMAGE_GENERIC_ROOT | DISSECT_IMAGE_REQUIRE_ROOT | DISSECT_IMAGE_RELAX_VAR_CHECK | - DISSECT_IMAGE_VALIDATE_OS, + DISSECT_IMAGE_VALIDATE_OS | + DISSECT_IMAGE_ALLOW_USERSPACE_VERITY, &mounted_dir, /* ret_dir_fd= */ NULL, &loop_device); diff --git a/src/machine-id-setup/machine-id-setup-main.c b/src/machine-id-setup/machine-id-setup-main.c index 59aad985f8d..bbc58945bd6 100644 --- a/src/machine-id-setup/machine-id-setup-main.c +++ b/src/machine-id-setup/machine-id-setup-main.c @@ -156,7 +156,8 @@ static int run(int argc, char *argv[]) { DISSECT_IMAGE_VALIDATE_OS | DISSECT_IMAGE_RELAX_VAR_CHECK | DISSECT_IMAGE_FSCK | - DISSECT_IMAGE_GROWFS, + DISSECT_IMAGE_GROWFS | + DISSECT_IMAGE_ALLOW_USERSPACE_VERITY, &mounted_dir, /* ret_dir_fd= */ NULL, &loop_device); diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 1cb039ade4a..c415d3cec14 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -3712,6 +3712,14 @@ static int setup_unix_export_host_inside(const char *directory, const char *unix return 0; } +static DissectImageFlags determine_dissect_image_flags(void) { + return + DISSECT_IMAGE_USR_NO_ROOT | + DISSECT_IMAGE_DISCARD_ON_LOOP | + (arg_read_only ? DISSECT_IMAGE_READ_ONLY : DISSECT_IMAGE_FSCK|DISSECT_IMAGE_GROWFS) | + DISSECT_IMAGE_ALLOW_USERSPACE_VERITY; +} + static int outer_child( Barrier *barrier, const char *directory, @@ -3773,10 +3781,8 @@ static int outer_child( arg_uid_shift, arg_uid_range, /* userns_fd= */ -EBADF, + determine_dissect_image_flags()| DISSECT_IMAGE_MOUNT_ROOT_ONLY| - DISSECT_IMAGE_DISCARD_ON_LOOP| - DISSECT_IMAGE_USR_NO_ROOT| - (arg_read_only ? DISSECT_IMAGE_READ_ONLY : DISSECT_IMAGE_FSCK|DISSECT_IMAGE_GROWFS)| (arg_start_mode == START_BOOT ? DISSECT_IMAGE_VALIDATE_OS : 0)); if (r < 0) return r; @@ -3958,10 +3964,8 @@ static int outer_child( arg_uid_shift, arg_uid_range, /* userns_fd= */ -EBADF, + determine_dissect_image_flags()| DISSECT_IMAGE_MOUNT_NON_ROOT_ONLY| - DISSECT_IMAGE_DISCARD_ON_LOOP| - DISSECT_IMAGE_USR_NO_ROOT| - (arg_read_only ? DISSECT_IMAGE_READ_ONLY : DISSECT_IMAGE_FSCK|DISSECT_IMAGE_GROWFS)| (idmap ? DISSECT_IMAGE_MOUNT_IDMAPPED : 0)); if (r == -EUCLEAN) return log_error_errno(r, "File system check for image failed: %m"); diff --git a/src/partition/repart.c b/src/partition/repart.c index 7735bd458af..db1d00974e3 100644 --- a/src/partition/repart.c +++ b/src/partition/repart.c @@ -7952,7 +7952,8 @@ static int run(int argc, char *argv[]) { DISSECT_IMAGE_GPT_ONLY | DISSECT_IMAGE_RELAX_VAR_CHECK | DISSECT_IMAGE_USR_NO_ROOT | - DISSECT_IMAGE_REQUIRE_ROOT, + DISSECT_IMAGE_REQUIRE_ROOT | + DISSECT_IMAGE_ALLOW_USERSPACE_VERITY, &mounted_dir, /* ret_dir_fd= */ NULL, &loop_device); diff --git a/src/portable/portable.c b/src/portable/portable.c index 27c18b117f2..2012dda835b 100644 --- a/src/portable/portable.c +++ b/src/portable/portable.c @@ -362,7 +362,13 @@ static int portable_extract_by_path( assert(path); - r = loop_device_make_by_path(path, O_RDONLY, /* sector_size= */ UINT32_MAX, LO_FLAGS_PARTSCAN, LOCK_SH, &d); + r = loop_device_make_by_path( + path, + O_RDONLY, + /* sector_size= */ UINT32_MAX, + LO_FLAGS_PARTSCAN, + LOCK_SH, + &d); if (r == -EISDIR) { _cleanup_free_ char *image_name = NULL; @@ -384,6 +390,21 @@ static int portable_extract_by_path( _cleanup_(rmdir_and_freep) char *tmpdir = NULL; _cleanup_close_pair_ int seq[2] = EBADF_PAIR; _cleanup_(sigkill_waitp) pid_t child = 0; + DissectImageFlags flags = + DISSECT_IMAGE_READ_ONLY | + DISSECT_IMAGE_GENERIC_ROOT | + DISSECT_IMAGE_REQUIRE_ROOT | + DISSECT_IMAGE_DISCARD_ON_LOOP | + DISSECT_IMAGE_RELAX_VAR_CHECK | + DISSECT_IMAGE_USR_NO_ROOT | + DISSECT_IMAGE_ADD_PARTITION_DEVICES | + DISSECT_IMAGE_PIN_PARTITION_DEVICES | + DISSECT_IMAGE_ALLOW_USERSPACE_VERITY; + + if (path_is_extension) + flags |= DISSECT_IMAGE_VALIDATE_OS_EXT | (relax_extension_release_check ? DISSECT_IMAGE_RELAX_EXTENSION_CHECK : 0); + else + flags |= DISSECT_IMAGE_VALIDATE_OS; /* We now have a loopback block device, let's fork off a child in its own mount namespace, mount it * there, and extract the metadata we need. The metadata is sent from the child back to us. */ @@ -399,14 +420,7 @@ static int portable_extract_by_path( /* verity= */ NULL, /* mount_options= */ NULL, image_policy, - DISSECT_IMAGE_READ_ONLY | - DISSECT_IMAGE_GENERIC_ROOT | - DISSECT_IMAGE_REQUIRE_ROOT | - DISSECT_IMAGE_DISCARD_ON_LOOP | - DISSECT_IMAGE_RELAX_VAR_CHECK | - DISSECT_IMAGE_USR_NO_ROOT | - DISSECT_IMAGE_ADD_PARTITION_DEVICES | - DISSECT_IMAGE_PIN_PARTITION_DEVICES, + flags, &m); if (r == -ENOPKG) sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Couldn't identify a suitable partition table or file system in '%s'.", path); @@ -428,15 +442,8 @@ static int portable_extract_by_path( if (r < 0) return r; if (r == 0) { - DissectImageFlags flags = DISSECT_IMAGE_READ_ONLY; - seq[0] = safe_close(seq[0]); - if (path_is_extension) - flags |= DISSECT_IMAGE_VALIDATE_OS_EXT | (relax_extension_release_check ? DISSECT_IMAGE_RELAX_EXTENSION_CHECK : 0); - else - flags |= DISSECT_IMAGE_VALIDATE_OS; - r = dissected_image_mount( m, tmpdir, diff --git a/src/shared/discover-image.c b/src/shared/discover-image.c index 6d4f7612caa..72f20c8eb7e 100644 --- a/src/shared/discover-image.c +++ b/src/shared/discover-image.c @@ -1471,8 +1471,25 @@ int image_read_metadata(Image *i, const ImagePolicy *image_policy) { case IMAGE_BLOCK: { _cleanup_(loop_device_unrefp) LoopDevice *d = NULL; _cleanup_(dissected_image_unrefp) DissectedImage *m = NULL; - - r = loop_device_make_by_path(i->path, O_RDONLY, /* sector_size= */ UINT32_MAX, LO_FLAGS_PARTSCAN, LOCK_SH, &d); + DissectImageFlags flags = + DISSECT_IMAGE_GENERIC_ROOT | + DISSECT_IMAGE_REQUIRE_ROOT | + DISSECT_IMAGE_RELAX_VAR_CHECK | + DISSECT_IMAGE_READ_ONLY | + DISSECT_IMAGE_USR_NO_ROOT | + DISSECT_IMAGE_ADD_PARTITION_DEVICES | + DISSECT_IMAGE_PIN_PARTITION_DEVICES | + DISSECT_IMAGE_VALIDATE_OS | + DISSECT_IMAGE_VALIDATE_OS_EXT | + DISSECT_IMAGE_ALLOW_USERSPACE_VERITY; + + r = loop_device_make_by_path( + i->path, + O_RDONLY, + /* sector_size= */ UINT32_MAX, + LO_FLAGS_PARTSCAN, + LOCK_SH, + &d); if (r < 0) return r; @@ -1481,20 +1498,12 @@ int image_read_metadata(Image *i, const ImagePolicy *image_policy) { /* verity= */ NULL, /* mount_options= */ NULL, image_policy, - DISSECT_IMAGE_GENERIC_ROOT | - DISSECT_IMAGE_REQUIRE_ROOT | - DISSECT_IMAGE_RELAX_VAR_CHECK | - DISSECT_IMAGE_READ_ONLY | - DISSECT_IMAGE_USR_NO_ROOT | - DISSECT_IMAGE_ADD_PARTITION_DEVICES | - DISSECT_IMAGE_PIN_PARTITION_DEVICES, + flags, &m); if (r < 0) return r; - r = dissected_image_acquire_metadata(m, - DISSECT_IMAGE_VALIDATE_OS | - DISSECT_IMAGE_VALIDATE_OS_EXT); + r = dissected_image_acquire_metadata(m, flags); if (r < 0) return r; diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index 216c036a31e..443cf53f528 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -2537,7 +2537,13 @@ static char* dm_deferred_remove_clean(char *name) { } DEFINE_TRIVIAL_CLEANUP_FUNC(char *, dm_deferred_remove_clean); -static int validate_signature_userspace(const VeritySettings *verity) { +static int validate_signature_userspace(const VeritySettings *verity, DissectImageFlags flags) { + + if (!FLAGS_SET(flags, DISSECT_IMAGE_ALLOW_USERSPACE_VERITY)) { + log_debug("Userspace dm-verity signature authentication disabled via flag."); + return 0; + } + #if HAVE_OPENSSL _cleanup_(sk_X509_free_allp) STACK_OF(X509) *sk = NULL; _cleanup_strv_free_ char **certs = NULL; @@ -2618,7 +2624,8 @@ static int validate_signature_userspace(const VeritySettings *verity) { static int do_crypt_activate_verity( struct crypt_device *cd, const char *name, - const VeritySettings *verity) { + const VeritySettings *verity, + DissectImageFlags flags) { bool check_signature; int r, k; @@ -2663,7 +2670,7 @@ static int do_crypt_activate_verity( /* Preferably propagate the original kernel error, so that the fallback logic can work, * as the device-mapper is finicky around concurrent activations of the same volume */ - k = validate_signature_userspace(verity); + k = validate_signature_userspace(verity, flags); if (k < 0) return r < 0 ? r : k; if (k == 0) @@ -2784,7 +2791,7 @@ static int verity_partition( goto check; /* The device already exists. Let's check it. */ /* The symlink to the device node does not exist yet. Assume not activated, and let's activate it. */ - r = do_crypt_activate_verity(cd, name, verity); + r = do_crypt_activate_verity(cd, name, verity, flags); if (r >= 0) goto try_open; /* The device is activated. Let's open it. */ /* libdevmapper can return EINVAL when the device is already in the activation stage. @@ -3966,10 +3973,12 @@ int verity_dissect_and_mount( if (r < 0) return log_debug_errno(r, "Failed to load root hash: %m"); - dissect_image_flags = (verity.data_path ? DISSECT_IMAGE_NO_PARTITION_TABLE : 0) | + dissect_image_flags = + (verity.data_path ? DISSECT_IMAGE_NO_PARTITION_TABLE : 0) | (relax_extension_release_check ? DISSECT_IMAGE_RELAX_EXTENSION_CHECK : 0) | DISSECT_IMAGE_ADD_PARTITION_DEVICES | - DISSECT_IMAGE_PIN_PARTITION_DEVICES; + DISSECT_IMAGE_PIN_PARTITION_DEVICES | + DISSECT_IMAGE_ALLOW_USERSPACE_VERITY; /* Note that we don't use loop_device_make here, as the FD is most likely O_PATH which would not be * accepted by LOOP_CONFIGURE, so just let loop_device_make_by_path reopen it as a regular FD. */ diff --git a/src/shared/dissect-image.h b/src/shared/dissect-image.h index 2366a383979..559d5b861d9 100644 --- a/src/shared/dissect-image.h +++ b/src/shared/dissect-image.h @@ -87,6 +87,7 @@ typedef enum DissectImageFlags { DISSECT_IMAGE_DISKSEQ_DEVNODE = 1 << 23, /* Prefer /dev/disk/by-diskseq/… device nodes */ DISSECT_IMAGE_ALLOW_EMPTY = 1 << 24, /* Allow that no usable partitions is present */ DISSECT_IMAGE_TRY_ATOMIC_MOUNT_EXCHANGE = 1 << 25, /* Try to mount the image beneath the specified mountpoint, rather than on top of it, and then umount the top */ + DISSECT_IMAGE_ALLOW_USERSPACE_VERITY = 1 << 26, /* Allow userspace verity keyring in /etc/verity.d/ and related dirs */ } DissectImageFlags; struct DissectedImage { diff --git a/src/shared/mount-util.c b/src/shared/mount-util.c index 77b18c375c2..72fa4fee43f 100644 --- a/src/shared/mount-util.c +++ b/src/shared/mount-util.c @@ -1214,7 +1214,9 @@ static int mount_in_namespace( (void) mkdir_parents(dest, 0755); if (img) { - DissectImageFlags f = DISSECT_IMAGE_TRY_ATOMIC_MOUNT_EXCHANGE; + DissectImageFlags f = + DISSECT_IMAGE_TRY_ATOMIC_MOUNT_EXCHANGE | + DISSECT_IMAGE_ALLOW_USERSPACE_VERITY; if (make_file_or_directory) f |= DISSECT_IMAGE_MKDIR; diff --git a/src/sysext/sysext.c b/src/sysext/sysext.c index 82255ebe994..2329081992e 100644 --- a/src/sysext/sysext.c +++ b/src/sysext/sysext.c @@ -1382,7 +1382,8 @@ static int merge_subprocess( DISSECT_IMAGE_MOUNT_ROOT_ONLY | DISSECT_IMAGE_USR_NO_ROOT | DISSECT_IMAGE_ADD_PARTITION_DEVICES | - DISSECT_IMAGE_PIN_PARTITION_DEVICES; + DISSECT_IMAGE_PIN_PARTITION_DEVICES | + DISSECT_IMAGE_ALLOW_USERSPACE_VERITY; r = verity_settings_load(&verity_settings, img->path, NULL, NULL); if (r < 0) diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 1ac7edbdd25..5241af5bfa2 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -1270,7 +1270,8 @@ static int run(int argc, char *argv[]) { DISSECT_IMAGE_GENERIC_ROOT | DISSECT_IMAGE_REQUIRE_ROOT | DISSECT_IMAGE_RELAX_VAR_CHECK | - DISSECT_IMAGE_VALIDATE_OS, + DISSECT_IMAGE_VALIDATE_OS | + DISSECT_IMAGE_ALLOW_USERSPACE_VERITY, &mounted_dir, /* ret_dir_fd= */ NULL, &loop_device); diff --git a/src/sysupdate/sysupdate.c b/src/sysupdate/sysupdate.c index 023eaac5866..2b88785e9fe 100644 --- a/src/sysupdate/sysupdate.c +++ b/src/sysupdate/sysupdate.c @@ -882,7 +882,8 @@ static int process_image( DISSECT_IMAGE_RELAX_VAR_CHECK | DISSECT_IMAGE_USR_NO_ROOT | DISSECT_IMAGE_GENERIC_ROOT | - DISSECT_IMAGE_REQUIRE_ROOT, + DISSECT_IMAGE_REQUIRE_ROOT | + DISSECT_IMAGE_ALLOW_USERSPACE_VERITY, &mounted_dir, /* ret_dir_fd= */ NULL, &loop_device); diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c index 6e28b1cf8ff..cc1c0a02056 100644 --- a/src/sysusers/sysusers.c +++ b/src/sysusers/sysusers.c @@ -2247,7 +2247,8 @@ static int run(int argc, char *argv[]) { DISSECT_IMAGE_VALIDATE_OS | DISSECT_IMAGE_RELAX_VAR_CHECK | DISSECT_IMAGE_FSCK | - DISSECT_IMAGE_GROWFS, + DISSECT_IMAGE_GROWFS | + DISSECT_IMAGE_ALLOW_USERSPACE_VERITY, &mounted_dir, /* ret_dir_fd= */ NULL, &loop_device); diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index 75db789f501..73880245568 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -4627,7 +4627,8 @@ static int run(int argc, char *argv[]) { DISSECT_IMAGE_VALIDATE_OS | DISSECT_IMAGE_RELAX_VAR_CHECK | DISSECT_IMAGE_FSCK | - DISSECT_IMAGE_GROWFS, + DISSECT_IMAGE_GROWFS | + DISSECT_IMAGE_ALLOW_USERSPACE_VERITY, &mounted_dir, /* ret_dir_fd= */ NULL, &loop_device); -- 2.47.3