[systemd-devel] [PATCH] PrivateDevices: fix /dev mount when a service is chrooted

Alban Crequy alban.crequy at gmail.com
Thu Feb 19 15:30:58 PST 2015


When a service uses both RootDirectory=/opt/... and PrivateDevices=true,
the private /dev must not be mounted in /dev but in /opt/.../dev.
---
 src/core/execute.c   |  6 +++++-
 src/core/namespace.c | 10 +++++-----
 src/core/namespace.h |  2 +-
 src/test/test-ns.c   |  2 +-
 4 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/src/core/execute.c b/src/core/execute.c
index 1815e3d..69b7990 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -1571,6 +1571,7 @@ static int exec_child(
             context->protect_home != PROTECT_HOME_NO) {
 
                 char *tmp = NULL, *var = NULL;
+                char private_dev_dir[512];
 
                 /* The runtime struct only contains the parent
                  * of the private /tmp, which is
@@ -1585,6 +1586,9 @@ static int exec_child(
                                 var = strjoina(runtime->var_tmp_dir, "/tmp");
                 }
 
+                if (params->apply_chroot && context->root_directory)
+                        snprintf(private_dev_dir, sizeof(private_dev_dir) - 1, "%s/dev", context->root_directory);
+
                 r = setup_namespace(
                                 context->read_write_dirs,
                                 context->read_only_dirs,
@@ -1592,7 +1596,7 @@ static int exec_child(
                                 tmp,
                                 var,
                                 params->bus_endpoint_path,
-                                context->private_devices,
+                                params->apply_chroot && context->private_devices ? private_dev_dir : NULL,
                                 context->protect_home,
                                 context->protect_system,
                                 context->mount_flags);
diff --git a/src/core/namespace.c b/src/core/namespace.c
index 4fecd32..7a6561a 100644
--- a/src/core/namespace.c
+++ b/src/core/namespace.c
@@ -234,7 +234,7 @@ static int mount_dev(BindMount *m) {
 
         dev_setup(temporary_mount);
 
-        if (mount(dev, "/dev/", NULL, MS_MOVE, NULL) < 0) {
+        if (mount(dev, m->path, NULL, MS_MOVE, NULL) < 0) {
                 r = -errno;
                 goto fail;
         }
@@ -419,7 +419,7 @@ int setup_namespace(
                 const char* tmp_dir,
                 const char* var_tmp_dir,
                 const char* bus_endpoint_path,
-                bool private_dev,
+                const char* private_dev_dir,
                 ProtectHome protect_home,
                 ProtectSystem protect_system,
                 unsigned long mount_flags) {
@@ -438,7 +438,7 @@ int setup_namespace(
                 strv_length(read_write_dirs) +
                 strv_length(read_only_dirs) +
                 strv_length(inaccessible_dirs) +
-                private_dev +
+                !!private_dev_dir +
                 (protect_home != PROTECT_HOME_NO ? 3 : 0) +
                 (protect_system != PROTECT_SYSTEM_NO ? 2 : 0) +
                 (protect_system == PROTECT_SYSTEM_FULL ? 1 : 0);
@@ -469,8 +469,8 @@ int setup_namespace(
                         m++;
                 }
 
-                if (private_dev) {
-                        m->path = "/dev";
+                if (private_dev_dir) {
+                        m->path = private_dev_dir;
                         m->mode = PRIVATE_DEV;
                         m++;
                 }
diff --git a/src/core/namespace.h b/src/core/namespace.h
index 42b92e7..4b06802 100644
--- a/src/core/namespace.h
+++ b/src/core/namespace.h
@@ -47,7 +47,7 @@ int setup_namespace(char **read_write_dirs,
                     const char *tmp_dir,
                     const char *var_tmp_dir,
                     const char *endpoint_path,
-                    bool private_dev,
+                    const char *private_dev_dir,
                     ProtectHome protect_home,
                     ProtectSystem protect_system,
                     unsigned long mount_flags);
diff --git a/src/test/test-ns.c b/src/test/test-ns.c
index 7cd7b77..d973d0d 100644
--- a/src/test/test-ns.c
+++ b/src/test/test-ns.c
@@ -60,7 +60,7 @@ int main(int argc, char *argv[]) {
                             tmp_dir,
                             var_tmp_dir,
                             NULL,
-                            true,
+                            "/dev",
                             PROTECT_HOME_NO,
                             PROTECT_SYSTEM_NO,
                             0);
-- 
2.1.4



More information about the systemd-devel mailing list