summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortopimiettinen <topimiettinen@users.noreply.github.com>2016-05-16 02:34:05 +0000
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2016-05-15 22:34:05 -0400
commit737ba3c82c71c15de498f63527d264dc996ffa11 (patch)
tree6db341e8a8664cd71a665a8d483ac44cf67b44b0
parent80f524a4c973654c5d82bf15598466b2f96a487d (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.xml5
-rw-r--r--src/core/namespace.c10
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)