From 10404d52e3402cd312a487fb88c23939ba35234a Mon Sep 17 00:00:00 2001 From: Djalal Harouni Date: Sun, 5 Mar 2017 21:19:29 +0100 Subject: [PATCH 1/2] namespace: create base-filesystem directories if RootImage= or RootDirectory= are set When a service is started with its own file system image, always try to create the base-filesystem directories that are needed. This implicitly covers the directories handled by MountAPIVFS= {/proc|/sys|/dev}. Mount protections or MountAPIVFS= mounts were never applied if we changed the root directory and the related paths were not present under the new root. The mounts were silently. Fix this by creating those directories if they are missing. Closes https://github.com/systemd/systemd/issues/5488 --- src/core/namespace.c | 5 +++++ src/shared/base-filesystem.c | 3 +++ 2 files changed, 8 insertions(+) diff --git a/src/core/namespace.c b/src/core/namespace.c index 4f29217bc4a..673b8364895 100644 --- a/src/core/namespace.c +++ b/src/core/namespace.c @@ -27,6 +27,7 @@ #include #include "alloc-util.h" +#include "base-filesystem.h" #include "dev-setup.h" #include "fd-util.h" #include "fs-util.h" @@ -1044,6 +1045,10 @@ int setup_namespace( } } + /* Try to set up the new root directory before mounting anything there */ + if (root_directory) + (void) base_filesystem_create(root_directory, UID_INVALID, GID_INVALID); + if (root_image) { r = dissected_image_mount(dissected_image, root_directory, dissect_image_flags); if (r < 0) diff --git a/src/shared/base-filesystem.c b/src/shared/base-filesystem.c index 127cbe44e38..5cbb2ec3dd1 100644 --- a/src/shared/base-filesystem.c +++ b/src/shared/base-filesystem.c @@ -51,6 +51,9 @@ static const BaseFilesystem table[] = { { "usr", 0755, NULL, NULL }, { "var", 0755, NULL, NULL }, { "etc", 0755, NULL, NULL }, + { "proc", 0755, NULL, NULL, true }, + { "sys", 0755, NULL, NULL, true }, + { "dev", 0755, NULL, NULL, true }, #if defined(__i386__) || defined(__x86_64__) { "lib64", 0, "usr/lib/x86_64-linux-gnu\0" "usr/lib64\0", "ld-linux-x86-64.so.2" }, From 9c988f934b6f1eebf9146b620a7d9e289ea69d9d Mon Sep 17 00:00:00 2001 From: Djalal Harouni Date: Sun, 5 Mar 2017 21:39:43 +0100 Subject: [PATCH 2/2] namespace: Apply MountAPIVFS= only when a Root directory is set The MountAPIVFS= documentation says that this options has no effect unless used in conjunction with RootDirectory= or RootImage= ,lets fix this and avoid to create private mount namespaces where it is not needed. --- src/core/execute.c | 2 +- src/core/namespace.c | 23 +++++++++++++++-------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/core/execute.c b/src/core/execute.c index d7798387c52..b2e6828239d 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -1670,7 +1670,7 @@ static bool exec_needs_mount_namespace( context->protect_control_groups) return true; - if (context->mount_apivfs) + if (context->mount_apivfs && (context->root_image || context->root_directory)) return true; return false; diff --git a/src/core/namespace.c b/src/core/namespace.c index 673b8364895..8235a64406e 100644 --- a/src/core/namespace.c +++ b/src/core/namespace.c @@ -816,18 +816,24 @@ static int make_read_only(MountEntry *m, char **blacklist) { return r; } -static bool namespace_info_mount_apivfs(const NameSpaceInfo *ns_info) { +static bool namespace_info_mount_apivfs(const char *root_directory, const NameSpaceInfo *ns_info) { assert(ns_info); - /* ProtectControlGroups= and ProtectKernelTunables= imply MountAPIVFS=, since to protect the API VFS mounts, - * they need to be around in the first place... */ + /* + * ProtectControlGroups= and ProtectKernelTunables= imply MountAPIVFS=, + * since to protect the API VFS mounts, they need to be around in the + * first place... and RootDirectory= or RootImage= need to be set. + */ - return ns_info->mount_apivfs || - ns_info->protect_control_groups || - ns_info->protect_kernel_tunables; + /* root_directory should point to a mount point */ + return root_directory && + (ns_info->mount_apivfs || + ns_info->protect_control_groups || + ns_info->protect_kernel_tunables); } static unsigned namespace_calculate_mounts( + const char* root_directory, const NameSpaceInfo *ns_info, char** read_write_paths, char** read_only_paths, @@ -864,7 +870,7 @@ static unsigned namespace_calculate_mounts( (ns_info->protect_control_groups ? 1 : 0) + (ns_info->protect_kernel_modules ? ELEMENTSOF(protect_kernel_modules_table) : 0) + protect_home_cnt + protect_system_cnt + - (namespace_info_mount_apivfs(ns_info) ? ELEMENTSOF(apivfs_table) : 0); + (namespace_info_mount_apivfs(root_directory, ns_info) ? ELEMENTSOF(apivfs_table) : 0); } int setup_namespace( @@ -932,6 +938,7 @@ int setup_namespace( } n_mounts = namespace_calculate_mounts( + root_directory, ns_info, read_write_paths, read_only_paths, @@ -1010,7 +1017,7 @@ int setup_namespace( if (r < 0) goto finish; - if (namespace_info_mount_apivfs(ns_info)) { + if (namespace_info_mount_apivfs(root_directory, ns_info)) { r = append_static_mounts(&m, apivfs_table, ELEMENTSOF(apivfs_table), ns_info->ignore_protect_paths); if (r < 0) goto finish;