diff options
author | topimiettinen <topimiettinen@users.noreply.github.com> | 2016-05-16 02:34:05 +0000 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2016-05-15 22:34:05 -0400 |
commit | 737ba3c82c71c15de498f63527d264dc996ffa11 (patch) | |
tree | 6db341e8a8664cd71a665a8d483ac44cf67b44b0 | |
parent | 80f524a4c973654c5d82bf15598466b2f96a487d (diff) |
namespace: Make private /dev noexec and readonly (#3263)
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().
-rw-r--r-- | man/systemd.exec.xml | 5 | ||||
-rw-r--r-- | src/core/namespace.c | 10 |
2 files changed, 11 insertions, 4 deletions
diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index 2a93760428..3cf6de8256 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -933,7 +933,10 @@ (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> diff --git a/src/core/namespace.c b/src/core/namespace.c index ef85bfec23..203d122810 100644 --- a/src/core/namespace.c +++ b/src/core/namespace.c @@ -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) |