]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sysext: default to a stricter image policy when reading /.extra/sysext/ DDIs
authorLennart Poettering <lennart@poettering.net>
Tue, 13 Dec 2022 15:27:48 +0000 (16:27 +0100)
committerLennart Poettering <lennart@poettering.net>
Wed, 5 Apr 2023 18:53:04 +0000 (20:53 +0200)
src/analyze/analyze-image-policy.c
src/shared/image-policy.c
src/shared/image-policy.h
src/sysext/sysext.c
src/test/test-image-policy.c

index e670fe5c4da424cde6e992e43fcfb8fd5b60a4d7..026216629c692c5569897a24b96d2032e4306d9b 100644 (file)
@@ -90,6 +90,8 @@ int verb_image_policy(int argc, char *argv[], void *userdata) {
                  * introspect our own defaults without guaranteeing API safety. */
                 if (streq(argv[i], "@sysext"))
                         p = &image_policy_sysext;
+                else if (streq(argv[i], "@sysext-strict"))
+                        p = &image_policy_sysext_strict;
                 else if (streq(argv[i], "@container"))
                         p = &image_policy_container;
                 else if (streq(argv[i], "@service"))
index 98c58c09010450d0be4918bb7569ed201e3aaee6..5baeac4c5d8b14e8ebad1f42851c60f36649e9b0 100644 (file)
@@ -631,6 +631,16 @@ const ImagePolicy image_policy_sysext = {
         .default_flags = PARTITION_POLICY_IGNORE,
 };
 
+const ImagePolicy image_policy_sysext_strict = {
+        /* For system extensions, requiring signing */
+        .n_policies = 2,
+        .policies = {
+                { PARTITION_ROOT,     PARTITION_POLICY_SIGNED|PARTITION_POLICY_ABSENT },
+                { PARTITION_USR,      PARTITION_POLICY_SIGNED|PARTITION_POLICY_ABSENT },
+        },
+        .default_flags = PARTITION_POLICY_IGNORE,
+};
+
 const ImagePolicy image_policy_container = {
         /* For systemd-nspawn containers we use all partitions, with the exception of swap */
         .n_policies = 8,
index 278c06c36a6d29c7ba6b27c9490fdf9efdb8128d..a5e37642afa0430c551ba6fc019767b4fd049140 100644 (file)
@@ -57,7 +57,8 @@ struct ImagePolicy {
 extern const ImagePolicy image_policy_allow;
 extern const ImagePolicy image_policy_deny;
 extern const ImagePolicy image_policy_ignore;
-extern const ImagePolicy image_policy_sysext;
+extern const ImagePolicy image_policy_sysext;        /* No verity required */
+extern const ImagePolicy image_policy_sysext_strict; /* Signed verity required */
 extern const ImagePolicy image_policy_container;
 extern const ImagePolicy image_policy_service;
 extern const ImagePolicy image_policy_host;
index ce076f665a6540ddc3f446b5c7fce8f498b7495a..f784627e82036860b5bdc794817fa562531c6c3a 100644 (file)
@@ -410,6 +410,24 @@ static int strverscmp_improvedp(char *const* a, char *const* b) {
         return strverscmp_improved(*a, *b);
 }
 
+static const ImagePolicy *pick_image_policy(const Image *img) {
+        assert(img);
+        assert(img->path);
+
+        /* Explicitly specified policy always wins */
+        if (arg_image_policy)
+                return arg_image_policy;
+
+        /* If located in /.extra/sysext/ in the initrd, then it was placed there by systemd-stub, and was
+         * picked up from an untrusted ESP. Thus, require a stricter policy by default for them. (For the
+         * other directories we assume the appropriate level of trust was already established already.  */
+
+        if (in_initrd() && path_startswith(img->path, "/.extra/sysext/"))
+                return &image_policy_sysext_strict;
+
+        return &image_policy_sysext;
+}
+
 static int merge_subprocess(Hashmap *images, const char *workspace) {
         _cleanup_free_ char *host_os_release_id = NULL, *host_os_release_version_id = NULL, *host_os_release_sysext_level = NULL,
                 *buf = NULL;
@@ -526,7 +544,7 @@ static int merge_subprocess(Hashmap *images, const char *workspace) {
                                         d,
                                         &verity_settings,
                                         /* mount_options= */ NULL,
-                                        arg_image_policy ?: &image_policy_sysext,
+                                        pick_image_policy(img),
                                         flags,
                                         &m);
                         if (r < 0)
index 8dc2044c4a5563fc1f6af33aaba233b7faad158e..41941704d42fc51ed31865b72fdab3549ba26a44 100644 (file)
@@ -77,6 +77,7 @@ TEST_RET(test_image_policy_to_string) {
         test_policy(&image_policy_ignore, "-");
         test_policy(&image_policy_deny, "~");
         test_policy(&image_policy_sysext, "sysext");
+        test_policy(&image_policy_sysext_strict, "sysext-strict");
         test_policy(&image_policy_container, "container");
         test_policy(&image_policy_host, "host");
         test_policy(&image_policy_service, "service");