]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Revert "Revert "Mount all fs nosuid when NoNewPrivileges=yes""
authorYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 25 Jun 2021 06:16:34 +0000 (15:16 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 25 Jun 2021 06:16:34 +0000 (15:16 +0900)
This reverts commit 1753d3021564671fba3d3196a84da657d15fb632.

Let's re-enable that feature now. As reported when the original commit
was merged, this causes some trouble on SELinux enabled systems. So,
in the subsequent commit, the feature will be disabled when SELinux is enabled.
But, anyway, this commit just re-enable that feature unconditionally.

man/systemd.exec.xml
src/core/execute.c
src/core/namespace.c
src/core/namespace.h

index 893b56d93ad1968070159578378f6a87006ea1fb..96d18dd93bd85e096522d1b6e38c1d737153c1bf 100644 (file)
@@ -675,9 +675,10 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
         <varname>SystemCallArchitectures=</varname>,
         <varname>SystemCallFilter=</varname>, or
         <varname>SystemCallLog=</varname> are specified. Note that even if this setting is overridden
-        by them, <command>systemctl show</command> shows the original value of this setting. Also see
-        <ulink url="https://www.kernel.org/doc/html/latest/userspace-api/no_new_privs.html">No New
-        Privileges Flag</ulink>.</para></listitem>
+        by them, <command>systemctl show</command> shows the original value of this setting. In case the
+        service will be run in a new mount namespace anyway, all file systems are mounted with MS_NOSUID
+        flag. Also see <ulink url="https://www.kernel.org/doc/html/latest/userspace-api/no_new_privs.html">
+        No New Privileges Flag</ulink>.</para></listitem>
       </varlistentry>
 
       <varlistentry>
index 42d76a346db45683c8a850d36cc2a4f74bd704fe..dcf683f68b912ffda7ae4090a587eab180cefeee 100644 (file)
@@ -3190,6 +3190,8 @@ static int apply_mount_namespace(
                         .protect_proc = context->protect_proc,
                         .proc_subset = context->proc_subset,
                         .private_ipc = context->private_ipc || context->ipc_namespace_path,
+                        /* If NNP is on, we can turn on MS_NOSUID, since it won't have any effect anymore. */
+                        .mount_nosuid = context->no_new_privileges,
                 };
         } else if (!context->dynamic_user && root_dir)
                 /*
index 6d77ce9967424c57e1fd313bcdce26a6d748f737..71fc73b9d30b81d40540e7725968298d16bff0f3 100644 (file)
@@ -1464,6 +1464,27 @@ static int make_noexec(const MountEntry *m, char **deny_list, FILE *proc_self_mo
         return 0;
 }
 
+static int make_nosuid(const MountEntry *m, FILE *proc_self_mountinfo) {
+        bool submounts = false;
+        int r = 0;
+
+        assert(m);
+        assert(proc_self_mountinfo);
+
+        submounts = !IN_SET(m->mode, EMPTY_DIR, TMPFS);
+
+        if (submounts)
+                r = bind_remount_recursive_with_mountinfo(mount_entry_path(m), MS_NOSUID, MS_NOSUID, NULL, proc_self_mountinfo);
+        else
+                r = bind_remount_one_with_mountinfo(mount_entry_path(m), MS_NOSUID, MS_NOSUID, proc_self_mountinfo);
+        if (r == -ENOENT && m->ignore)
+                return 0;
+        if (r < 0)
+                return log_debug_errno(r, "Failed to re-mount '%s'%s: %m", mount_entry_path(m),
+                                       submounts ? " and its submounts" : "");
+        return 0;
+}
+
 static bool namespace_info_mount_apivfs(const NamespaceInfo *ns_info) {
         assert(ns_info);
 
@@ -1660,6 +1681,17 @@ static int apply_mounts(
                 }
         }
 
+        /* Fourth round, flip the nosuid bits without a deny list. */
+        if (ns_info->mount_nosuid)
+                for (MountEntry *m = mounts; m < mounts + *n_mounts; ++m) {
+                        r = make_nosuid(m, proc_self_mountinfo);
+                        if (r < 0) {
+                                if (error_path && mount_entry_path(m))
+                                        *error_path = strdup(mount_entry_path(m));
+                                return r;
+                        }
+                }
+
         return 1;
 }
 
index 737d6eae8b1e5d25d66fdc4d9e280bb971b4d94f..c9373a4adb1057ae63692d33242a1664f4e5a33f 100644 (file)
@@ -74,6 +74,7 @@ struct NamespaceInfo {
         bool mount_apivfs;
         bool protect_hostname;
         bool private_ipc;
+        bool mount_nosuid;
         ProtectHome protect_home;
         ProtectSystem protect_system;
         ProtectProc protect_proc;