[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