diff --git a/src/core/execute.c b/src/core/execute.c index f6c4b4676ed..e97651105ee 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 4f29217bc4a..8235a64406e 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" @@ -815,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, @@ -863,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( @@ -931,6 +938,7 @@ int setup_namespace( } n_mounts = namespace_calculate_mounts( + root_directory, ns_info, read_write_paths, read_only_paths, @@ -1009,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; @@ -1044,6 +1052,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 f2d8bcf6e36..903a1878611 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" },