]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
systemd-confext: mount confexts as noexec and nosuid
authorLuca Boccassi <bluca@debian.org>
Thu, 6 Apr 2023 11:19:22 +0000 (12:19 +0100)
committerMike Yuan <me@yhndnzj.com>
Thu, 13 Apr 2023 17:21:48 +0000 (01:21 +0800)
Confexts should not contain code, so mount confexts with noexec.
We cannot mount invidial extensions as noexec, as the overlay ignores
it and bypasses it, we need to use the flag on the whole overlay for
it to be effective.
But given there are legacy scripts still shipped in /etc, allow to
override it with --noexec=false.

man/systemd-sysext.xml
src/sysext/sysext.c
test/units/testsuite-50.sh

index 6e164077e2e897444d25a27ad8858ed7126f07aa..5e8d11ef3d14eeaaaa526c10d4fc999dc4ff0ce9 100644 (file)
     <command>confext</command> will extend only <filename>/etc</filename>. Files and directories contained
     in the confext images outside of the <filename>/etc/</filename> hierarchy are <emphasis>not</emphasis>
     merged, and hence have no effect when included in the image. Formats for these images are of the
-    same as sysext images.</para>
+    same as sysext images. The merged hierarchy will be mounted with <literal>nosuid</literal> and
+    (if not disabled via <option>--noexec=false</option>) <literal>noexec</literal>.</para>
 
     <para>Confexts are looked for in the directories <filename>/run/confexts/</filename>,
     <filename>/var/lib/confexts/</filename>, <filename>/usr/lib/confexts/</filename> and
         see above for details.</para></listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><option>--noexec=</option><replaceable>BOOL</replaceable></term>
+
+        <listitem><para>When merging configuration extensions into <filename>/etc/</filename> the
+        <literal>MS_NOEXEC</literal> mount flag is used by default. This option can be used to disable
+        it.</para></listitem>
+      </varlistentry>
+
       <xi:include href="standard-options.xml" xpointer="no-pager" />
       <xi:include href="standard-options.xml" xpointer="no-legend" />
       <xi:include href="standard-options.xml" xpointer="json" />
index e23785cc56b83856f7ffc32916a412fa6c12e494..27ab57e119f1369fa4c068f410b174e903dba9d4 100644 (file)
@@ -45,6 +45,7 @@ static JsonFormatFlags arg_json_format_flags = JSON_FORMAT_OFF;
 static PagerFlags arg_pager_flags = 0;
 static bool arg_legend = true;
 static bool arg_force = false;
+static int arg_noexec = -1;
 static ImagePolicy *arg_image_policy = NULL;
 
 /* Is set to IMAGE_CONFEXT when systemd is called with the confext functionality instead of the default */
@@ -64,6 +65,7 @@ static const struct {
         const char *scope_env;
         const char *name_env;
         const ImagePolicy *default_image_policy;
+        unsigned long default_mount_flags;
 } image_class_info[_IMAGE_CLASS_MAX] = {
         [IMAGE_SYSEXT] = {
                 .dot_directory_name = ".systemd-sysext",
@@ -74,6 +76,7 @@ static const struct {
                 .scope_env = "SYSEXT_SCOPE",
                 .name_env = "SYSTEMD_SYSEXT_HIERARCHIES",
                 .default_image_policy = &image_policy_sysext,
+                .default_mount_flags = MS_RDONLY|MS_NODEV,
         },
         [IMAGE_CONFEXT] = {
                 .dot_directory_name = ".systemd-confext",
@@ -84,6 +87,7 @@ static const struct {
                 .scope_env = "CONFEXT_SCOPE",
                 .name_env = "SYSTEMD_CONFEXT_HIERARCHIES",
                 .default_image_policy = &image_policy_confext,
+                .default_mount_flags = MS_RDONLY|MS_NODEV|MS_NOSUID|MS_NOEXEC,
         }
 };
 
@@ -288,6 +292,7 @@ static int mount_overlayfs(
 
         _cleanup_free_ char *options = NULL;
         bool separator = false;
+        unsigned long flags;
         int r;
 
         assert(where);
@@ -309,8 +314,12 @@ static int mount_overlayfs(
                 separator = true;
         }
 
+        flags = image_class_info[arg_image_class].default_mount_flags;
+        if (arg_noexec >= 0)
+                SET_FLAG(flags, MS_NOEXEC, arg_noexec);
+
         /* Now mount the actual overlayfs */
-        r = mount_nofollow_verbose(LOG_ERR, image_class_info[arg_image_class].short_identifier, where, "overlay", MS_RDONLY, options);
+        r = mount_nofollow_verbose(LOG_ERR, image_class_info[arg_image_class].short_identifier, where, "overlay", flags, options);
         if (r < 0)
                 return r;
 
@@ -948,6 +957,7 @@ static int verb_help(int argc, char **argv, void *userdata) {
                "     --force              Ignore version incompatibilities\n"
                "     --image-policy=POLICY\n"
                "                          Specify disk image dissection policy\n"
+               "     --noexec=BOOL        Whether to mount extension overlay with noexec\n"
                "\nSee the %2$s for details.\n",
                program_invocation_short_name,
                link,
@@ -969,6 +979,7 @@ static int parse_argv(int argc, char *argv[]) {
                 ARG_JSON,
                 ARG_FORCE,
                 ARG_IMAGE_POLICY,
+                ARG_NOEXEC,
         };
 
         static const struct option options[] = {
@@ -980,6 +991,7 @@ static int parse_argv(int argc, char *argv[]) {
                 { "json",         required_argument, NULL, ARG_JSON         },
                 { "force",        no_argument,       NULL, ARG_FORCE        },
                 { "image-policy", required_argument, NULL, ARG_IMAGE_POLICY },
+                { "noexec",       required_argument, NULL, ARG_NOEXEC       },
                 {}
         };
 
@@ -1029,6 +1041,14 @@ static int parse_argv(int argc, char *argv[]) {
                                 return r;
                         break;
 
+                case ARG_NOEXEC:
+                        r = parse_boolean_argument("--noexec", optarg, NULL);
+                        if (r < 0)
+                                return r;
+
+                        arg_noexec = r;
+                        break;
+
                 case '?':
                         return -EINVAL;
 
index 52634c64b2d46e4571cac0167a235843ea8ba9e3..f6b2467a989729045574d6ed4c25b461978ac956 100755 (executable)
@@ -515,8 +515,14 @@ mkdir -p /run/confexts/test/etc/extension-release.d
 echo "ID=_any" >/run/confexts/test/etc/extension-release.d/extension-release.test
 echo "ARCHITECTURE=_any" >>/run/confexts/test/etc/extension-release.d/extension-release.test
 echo "MARKER_CONFEXT_123" >/run/confexts/test/etc/testfile
+cat <<EOF>/run/confexts/test/etc/testscript
+#!/bin/bash
+echo "This should not happen"
+EOF
+chmod +x /run/confexts/test/etc/testscript
 systemd-confext merge
 grep -q -F "MARKER_CONFEXT_123" /etc/testfile
+/etc/testscript && { echo 'unexpected success'; exit 1; }
 systemd-confext status
 systemd-confext unmerge
 rm -rf /run/confexts/