]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Merge pull request #31531 from poettering/verity-userspace-optional
authorLennart Poettering <lennart@poettering.net>
Wed, 28 Feb 2024 21:04:58 +0000 (22:04 +0100)
committerGitHub <noreply@github.com>
Wed, 28 Feb 2024 21:04:58 +0000 (22:04 +0100)
dissect: make use of userspace verity keyring optional

23 files changed:
docs/ENVIRONMENT.md
man/kernel-command-line.xml
src/analyze/analyze.c
src/boot/bootctl.c
src/core/namespace.c
src/coredump/coredumpctl.c
src/dissect/dissect.c
src/firstboot/firstboot.c
src/journal/journalctl.c
src/kernel-install/kernel-install.c
src/machine-id-setup/machine-id-setup-main.c
src/nspawn/nspawn.c
src/partition/repart.c
src/portable/portable.c
src/shared/discover-image.c
src/shared/dissect-image.c
src/shared/dissect-image.h
src/shared/mount-util.c
src/sysext/sysext.c
src/systemctl/systemctl.c
src/sysupdate/sysupdate.c
src/sysusers/sysusers.c
src/tmpfiles/tmpfiles.c

index d55bcaf802f03092823f4c2f60b79528357b2bf8..302ca67b576d4bbee0c94ff3eb54f82d534c9999 100644 (file)
@@ -488,6 +488,12 @@ disk images with `--image=` or similar:
   devices when opening them. Defaults to on, set this to "0" to disable this
   feature.
 
+* `$SYSTEMD_ALLOW_USERSPACE_VERITY` — takes a boolean, which controls whether
+  to consider the userspace Verity public key store in `/etc/verity.d/` (and
+  related directories) to authenticate signatures on Verity hashes of disk
+  images. Defaults to true, i.e. userspace signature validation is allowed. If
+  false, authentication can be done only via the kernel's internal keyring.
+
 `systemd-cryptsetup`:
 
 * `$SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE` – takes a boolean, which controls
index 1629ab2f2b33be5f91ad8aea42f9a27d7f311a94..72003d86f2fd16d0e87caf064aa923d83aff88b8 100644 (file)
         </listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><varname>systemd.allow_userspace_verity=</varname></term>
+
+        <listitem><para>Takes a boolean argument. Controls whether disk images that are Verity protected may
+        be authenticated in userspace signature checks via <filename>/etc/verity.d/</filename> (and related
+        directories) public key drop-ins, or whether in-kernel signature checking only. Defaults to
+        on.</para>
+
+        <xi:include href="version-info.xml" xpointer="v256"/></listitem>
+      </varlistentry>
+
       <varlistentry>
         <term><varname>systemd.hostname=</varname></term>
 
index ea906c7bfeb57b29b69735caaf3f643241752898..b449e538f31e33b82d4e4763075353c10b8b68bc 100644 (file)
@@ -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);
index bd10c08b82eaa1aad093996c4a42aeeab14d99ba..b883159dcf1a4dbad417e6f7e2239f7e5e03bac8 100644 (file)
@@ -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);
index e55982ffa5b06656e45279280028adfeafc1069d..855ad0de8934480d3b51e14639434f79969984da 100644 (file)
@@ -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);
index 53769f8d4c6005373b40bbf332e735ecb82c594b..52ded50776c2312b222a4033b6b6b591b1b53cf0 100644 (file)
@@ -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);
index 27669902969dfca418176fda0e61e4347a235c58..bef75289777eb4151c30ffe0141a37fc1dcdbe4f 100644 (file)
@@ -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;
index d9d2e282519b6efb4c1427dd1cfc435507ec1915..7f6c1461209eebb181fe9991595babcdeb623747 100644 (file)
@@ -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);
index 6262dd0aa6b0593afbc047e3162ab192702e9262..6f83585db5ffb4e2225f18ad29bb11cfe0095fce 100644 (file)
@@ -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);
index 2523d43944959bd62e65cc5ce6b5b0c7ca5804cd..273c1d9c4728104f47edafd8297cc0bebec2196c 100644 (file)
@@ -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);
index 59aad985f8d6ef5f1be640a05dde95cf47e466bc..bbc58945bd6e3d48682c408852784bb7dc293860 100644 (file)
@@ -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);
index 1cb039ade4ae99407ee11fe1dd6bc332034a0ac3..c415d3cec1416a7eb53b8e547072da18acac6194 100644 (file)
@@ -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");
index 7735bd458af33b78c7dd1bd67f231b06600041e3..db1d00974e3771058b7122b58b8da69689fe65f7 100644 (file)
@@ -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);
index 27c18b117f2cbc963f35ebddc9b784194d420e06..2012dda835bf58561485e0ba96dda9daf6ebcc56 100644 (file)
@@ -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,
index 6d4f7612caac15c1ff3e4c00c01816817d7c8026..72f20c8eb7e24aa52eeb74888a70437c9c54f6bb 100644 (file)
@@ -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;
 
index 763fdf1cbf03a5d502d5871b99667f6326172379..de13fa3bc30c7378fadefc1cdfd91593452d193e 100644 (file)
@@ -60,6 +60,7 @@
 #include "openssl-util.h"
 #include "os-util.h"
 #include "path-util.h"
+#include "proc-cmdline.h"
 #include "process-util.h"
 #include "raw-clone.h"
 #include "resize-fs.h"
@@ -2537,7 +2538,35 @@ 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) {
+        int r;
+
+        if (!FLAGS_SET(flags, DISSECT_IMAGE_ALLOW_USERSPACE_VERITY)) {
+                log_debug("Userspace dm-verity signature authentication disabled via flag.");
+                return 0;
+        }
+
+        r = getenv_bool_secure("SYSTEMD_ALLOW_USERSPACE_VERITY");
+        if (r < 0 && r != -ENXIO) {
+                log_debug_errno(r, "Failed to parse $SYSTEMD_ALLOW_USERSPACE_VERITY environment variable, refusing userspace dm-verity signature authentication.");
+                return 0;
+        }
+        if (!r) {
+                log_debug("Userspace dm-verity signature authentication disabled via $SYSTEMD_ALLOW_USERSPACE_VERITY environment variable.");
+                return 0;
+        }
+
+        bool b;
+        r = proc_cmdline_get_bool("systemd.allow_userspace_verity", PROC_CMDLINE_TRUE_WHEN_MISSING, &b);
+        if (r < 0) {
+                log_debug_errno(r, "Failed to parse systemd.allow_userspace_verity= kernel command line option, refusing userspace dm-verity signature authentication.");
+                return 0;
+        }
+        if (!b) {
+                log_debug("Userspace dm-verity signature authentication disabled via systemd.allow_userspace_verity= kernel command line variable.");
+                return 0;
+        }
+
 #if HAVE_OPENSSL
         _cleanup_(sk_X509_free_allp) STACK_OF(X509) *sk = NULL;
         _cleanup_strv_free_ char **certs = NULL;
@@ -2546,7 +2575,6 @@ static int validate_signature_userspace(const VeritySettings *verity) {
         _cleanup_(BIO_freep) BIO *bio = NULL; /* 'bio' must be freed first, 's' second, hence keep this order
                                                * of declaration in place, please */
         const unsigned char *d;
-        int r;
 
         assert(verity);
         assert(verity->root_hash);
@@ -2618,7 +2646,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 +2692,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 +2813,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 +3995,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. */
index 2366a383979499df720d4de496ea9f2219f90a7d..559d5b861d9288eef6397fed4dddacb2a3d0cad2 100644 (file)
@@ -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 {
index 77b18c375c240e5a8d9d494445d80a5640a78d8f..72fa4fee43fe4cee69096e0c40f2c7cb0651d4a0 100644 (file)
@@ -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;
index 82255ebe9943b8af175079ff100b268f90ebb6f7..2329081992e7da23d7ee213075db9dd57ea5034e 100644 (file)
@@ -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)
index 1ac7edbdd2586684c19da42a5da915d276b691d5..5241af5bfa2c4cce2070fe72ebce2b656a16736c 100644 (file)
@@ -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);
index 023eaac5866b1f8517feb677926d42105d1d7415..2b88785e9fe484247a1cdfe1bd3d3150d3f63996 100644 (file)
@@ -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);
index e443b1021160e3b4dc6b302a14587fd3ce42700b..89e957822a620bf8c8919750afb85138d79f07d5 100644 (file)
@@ -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);
index 75db789f5013be30b3ee027d3118be8482b39af3..73880245568917f7dd2a91876771c94d0c6da995 100644 (file)
@@ -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);