5d2ee9
From 11f5677752f9b78239214b3064e5a2c3712d71b1 Mon Sep 17 00:00:00 2001
5d2ee9
From: Lennart Poettering <lennart@poettering.net>
5d2ee9
Date: Wed, 20 Mar 2019 20:19:38 +0100
5d2ee9
Subject: [PATCH] core: imply NNP and SUID/SGID restriction for DynamicUser=yes
5d2ee9
 service
5d2ee9
5d2ee9
Let's be safe, rather than sorry. This way DynamicUser=yes services can
5d2ee9
neither take benefit of, nor create SUID/SGID binaries.
5d2ee9
5d2ee9
Given that DynamicUser= is a recent addition only we should be able to
5d2ee9
get away with turning this on, even though this is strictly speaking a
5d2ee9
binary compatibility breakage.
5d2ee9
5d2ee9
(cherry picked from commit bf65b7e0c9fc215897b676ab9a7c9d1c688143ba)
5d2ee9
Resolves: #1687512
5d2ee9
---
5d2ee9
 man/systemd.exec.xml | 16 ++++++++++------
5d2ee9
 src/core/unit.c      | 10 ++++++++--
5d2ee9
 2 files changed, 18 insertions(+), 8 deletions(-)
5d2ee9
5d2ee9
diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml
5d2ee9
index 45ed1864f8..bdaed68162 100644
5d2ee9
--- a/man/systemd.exec.xml
5d2ee9
+++ b/man/systemd.exec.xml
5d2ee9
@@ -229,7 +229,9 @@
5d2ee9
         created by the executed processes is bound to the runtime of the service, and hence the lifetime of the dynamic
5d2ee9
         user/group. Since <filename>/tmp</filename> and <filename>/var/tmp</filename> are usually the only
5d2ee9
         world-writable directories on a system this ensures that a unit making use of dynamic user/group allocation
5d2ee9
-        cannot leave files around after unit termination. Moreover <varname>ProtectSystem=strict</varname> and
5d2ee9
+        cannot leave files around after unit termination. Furthermore <varname>NoNewPrivileges=</varname> and
5d2ee9
+        <varname>RestrictSUIDSGID=</varname> are implicitly enabled to ensure that processes invoked cannot take benefit
5d2ee9
+        or create SUID/SGID files or directories. Moreover <varname>ProtectSystem=strict</varname> and
5d2ee9
         <varname>ProtectHome=read-only</varname> are implied, thus prohibiting the service to write to arbitrary file
5d2ee9
         system locations. In order to allow the service to write to certain directories, they have to be whitelisted
5d2ee9
         using <varname>ReadWritePaths=</varname>, but care must be taken so that UID/GID recycling doesn't create
5d2ee9
@@ -357,11 +359,12 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
5d2ee9
         <varname>RestrictAddressFamilies=</varname>, <varname>RestrictNamespaces=</varname>,
5d2ee9
         <varname>PrivateDevices=</varname>, <varname>ProtectKernelTunables=</varname>,
5d2ee9
         <varname>ProtectKernelModules=</varname>, <varname>MemoryDenyWriteExecute=</varname>,
5d2ee9
-        <varname>RestrictRealtime=</varname>, <varname>RestrictSUIDSGID=</varname> or
5d2ee9
-        <varname>LockPersonality=</varname> are specified. Note that even if this setting is overridden by
5d2ee9
-        them, <command>systemctl show</command> shows the original value of this setting. Also see 
5d2ee9
+        <varname>RestrictRealtime=</varname>, <varname>RestrictSUIDSGID=</varname>,
5d2ee9
+        <varname>DynamicUser=</varname> or <varname>LockPersonality=</varname> are specified. Note that even
5d2ee9
+        if this setting is overridden by them, <command>systemctl show</command> shows the original value of
5d2ee9
+        this setting. Also see 
5d2ee9
         url="https://www.kernel.org/doc/html/latest/userspace-api/no_new_privs.html">No New Privileges
5d2ee9
-        Flag</ulink>.  </para></listitem>
5d2ee9
+        Flag</ulink>.</para></listitem>
5d2ee9
       </varlistentry>
5d2ee9
 
5d2ee9
       <varlistentry>
5d2ee9
@@ -1288,7 +1291,8 @@ RestrictNamespaces=~cgroup net</programlisting>
5d2ee9
         identity of other users, it is recommended to restrict creation of SUID/SGID files to the few
5d2ee9
         programs that actually require them. Note that this restricts marking of any type of file system
5d2ee9
         object with these bits, including both regular files and directories (where the SGID is a different
5d2ee9
-        meaning than for files, see documentation). Defaults to off.</para></listitem>
5d2ee9
+        meaning than for files, see documentation). This option is implied if <varname>DynamicUser=</varname>
5d2ee9
+        is enabled. Defaults to off.</para></listitem>
5d2ee9
       </varlistentry>
5d2ee9
 
5d2ee9
       <varlistentry>
5d2ee9
diff --git a/src/core/unit.c b/src/core/unit.c
5d2ee9
index 115739f4c6..e1f5e6f7bd 100644
5d2ee9
--- a/src/core/unit.c
5d2ee9
+++ b/src/core/unit.c
5d2ee9
@@ -4161,14 +4161,20 @@ int unit_patch_contexts(Unit *u) {
5d2ee9
                                         return -ENOMEM;
5d2ee9
                         }
5d2ee9
 
5d2ee9
-                        /* If the dynamic user option is on, let's make sure that the unit can't leave its UID/GID
5d2ee9
-                         * around in the file system or on IPC objects. Hence enforce a strict sandbox. */
5d2ee9
+                        /* If the dynamic user option is on, let's make sure that the unit can't leave its
5d2ee9
+                         * UID/GID around in the file system or on IPC objects. Hence enforce a strict
5d2ee9
+                         * sandbox. */
5d2ee9
 
5d2ee9
                         ec->private_tmp = true;
5d2ee9
                         ec->remove_ipc = true;
5d2ee9
                         ec->protect_system = PROTECT_SYSTEM_STRICT;
5d2ee9
                         if (ec->protect_home == PROTECT_HOME_NO)
5d2ee9
                                 ec->protect_home = PROTECT_HOME_READ_ONLY;
5d2ee9
+
5d2ee9
+                        /* Make sure this service can neither benefit from SUID/SGID binaries nor create
5d2ee9
+                         * them. */
5d2ee9
+                        ec->no_new_privileges = true;
5d2ee9
+                        ec->restrict_suid_sgid = true;
5d2ee9
                 }
5d2ee9
         }
5d2ee9