]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
namespace: Make private /dev noexec and readonly (#3263)
authortopimiettinen <topimiettinen@users.noreply.github.com>
Mon, 16 May 2016 02:34:05 +0000 (02:34 +0000)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Mon, 16 May 2016 02:34:05 +0000 (22:34 -0400)
Private /dev will not be managed by udev or others, so we can make it
noexec and readonly after we have made all device nodes. As /dev/shm
needs to be writable, we can't use bind_remount_recursive().

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

index 2a937604288c9ac88efd8ab34e0c7b20dc1d485d..3cf6de82563de5c90bd3688313893209031010c7 100644 (file)
         (propagation in the opposite direction continues to work).
         This means that this setting may not be used for services
         which shall be able to install mount points in the main mount
-        namespace.</para></listitem>
+        namespace. The /dev namespace will be mounted read-only and 'noexec'.
+        The latter may break old programs which try to set up executable
+        memory by using <citerefentry><refentrytitle>mmap</refentrytitle><manvolnum>2</manvolnum></citerefentry>
+        of <filename>/dev/zero</filename> instead of using <constant>MAP_ANON</constant>.</para></listitem>
       </varlistentry>
 
       <varlistentry>
index ef85bfec237887239c32c324aa9532b71502e008..203d1228102b06d8a72ae22b7b2af08540e25eb6 100644 (file)
@@ -44,6 +44,8 @@
 #include "user-util.h"
 #include "util.h"
 
+#define DEV_MOUNT_OPTIONS (MS_NOSUID|MS_STRICTATIME|MS_NOEXEC)
+
 typedef enum MountMode {
         /* This is ordered by priority! */
         INACCESSIBLE,
@@ -153,7 +155,7 @@ static int mount_dev(BindMount *m) {
 
         dev = strjoina(temporary_mount, "/dev");
         (void) mkdir(dev, 0755);
-        if (mount("tmpfs", dev, "tmpfs", MS_NOSUID|MS_STRICTATIME, "mode=755") < 0) {
+        if (mount("tmpfs", dev, "tmpfs", DEV_MOUNT_OPTIONS, "mode=755") < 0) {
                 r = -errno;
                 goto fail;
         }
@@ -330,9 +332,11 @@ static int make_read_only(BindMount *m) {
 
         if (IN_SET(m->mode, INACCESSIBLE, READONLY))
                 r = bind_remount_recursive(m->path, true);
-        else if (IN_SET(m->mode, READWRITE, PRIVATE_TMP, PRIVATE_VAR_TMP, PRIVATE_DEV))
+        else if (IN_SET(m->mode, READWRITE, PRIVATE_TMP, PRIVATE_VAR_TMP, PRIVATE_DEV)) {
                 r = bind_remount_recursive(m->path, false);
-        else
+                if (r == 0 && m->mode == PRIVATE_DEV) /* can be readonly but the submounts can't*/
+                        r = mount(NULL, m->path, NULL, MS_REMOUNT|DEV_MOUNT_OPTIONS|MS_RDONLY, NULL);
+        } else
                 r = 0;
 
         if (m->ignore && r == -ENOENT)