From 80271a446c8d8b52fee907b8c4de8ea2adcb7f15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?X=E2=84=B9=20Ruoyao?= Date: Thu, 4 Mar 2021 00:08:09 +0800 Subject: [PATCH] Remount /dev/mqueue in unshared mount namespace for PrivateIPC --- src/core/execute.c | 5 ++++- src/core/namespace.c | 34 +++++++++++++++++++++++++++++++++- src/core/namespace.h | 1 + 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/core/execute.c b/src/core/execute.c index 684b5a233e..0214cee65e 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -2037,7 +2037,9 @@ bool exec_needs_mount_namespace( context->protect_kernel_logs || context->protect_control_groups || context->protect_proc != PROTECT_PROC_DEFAULT || - context->proc_subset != PROC_SUBSET_ALL) + context->proc_subset != PROC_SUBSET_ALL || + context->private_ipc || + context->ipc_namespace_path) return true; if (context->root_directory) { @@ -3178,6 +3180,7 @@ static int apply_mount_namespace( .protect_system = context->protect_system, .protect_proc = context->protect_proc, .proc_subset = context->proc_subset, + .private_ipc = context->private_ipc || context->ipc_namespace_path, }; } else if (!context->dynamic_user && root_dir) /* diff --git a/src/core/namespace.c b/src/core/namespace.c index d484ce7d67..c5897c6c94 100644 --- a/src/core/namespace.c +++ b/src/core/namespace.c @@ -64,6 +64,7 @@ typedef enum MountMode { EXEC, TMPFS, EXTENSION_IMAGES, /* Mounted outside the root directory, and used by subsequent mounts */ + MQUEUEFS, READWRITE_IMPLICIT, /* Should have the lowest priority. */ _MOUNT_MODE_MAX, } MountMode; @@ -228,6 +229,7 @@ static const char * const mount_mode_table[_MOUNT_MODE_MAX] = { [READWRITE_IMPLICIT] = "rw-implicit", [EXEC] = "exec", [NOEXEC] = "noexec", + [MQUEUEFS] = "mqueuefs", }; DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(mount_mode, MountMode); @@ -1113,6 +1115,24 @@ static int mount_run(const MountEntry *m) { return mount_tmpfs(m); } +static int mount_mqueuefs(const MountEntry *m) { + int r; + const char *entry_path; + + assert(m); + + entry_path = mount_entry_path(m); + + (void) mkdir_p_label(entry_path, 0755); + (void) umount_recursive(entry_path, 0); + + r = mount_nofollow_verbose(LOG_DEBUG, "mqueue", entry_path, "mqueue", m->flags, mount_entry_options(m)); + if (r < 0) + return r; + + return 0; +} + static int mount_image(const MountEntry *m, const char *root_directory) { _cleanup_free_ char *host_os_release_id = NULL, *host_os_release_version_id = NULL, @@ -1317,6 +1337,9 @@ static int apply_one_mount( case RUN: return mount_run(m); + case MQUEUEFS: + return mount_mqueuefs(m); + case MOUNT_IMAGES: return mount_image(m, NULL); @@ -1516,7 +1539,8 @@ static size_t namespace_calculate_mounts( (creds_path ? 2 : 1) + !!log_namespace + setup_propagate + /* /run/systemd/incoming */ - !!notify_socket; + !!notify_socket + + ns_info->private_ipc; /* /dev/mqueue */ } static void normalize_mounts(const char *root_directory, MountEntry *mounts, size_t *n_mounts) { @@ -2027,6 +2051,14 @@ int setup_namespace( }; } + if (ns_info->private_ipc) { + *(m++) = (MountEntry) { + .path_const = "/dev/mqueue", + .mode = MQUEUEFS, + .flags = MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_RELATIME, + }; + } + if (creds_path) { /* If our service has a credentials store configured, then bind that one in, but hide * everything else. */ diff --git a/src/core/namespace.h b/src/core/namespace.h index 81bce82555..2806db8fd1 100644 --- a/src/core/namespace.h +++ b/src/core/namespace.h @@ -73,6 +73,7 @@ struct NamespaceInfo { bool protect_kernel_logs; bool mount_apivfs; bool protect_hostname; + bool private_ipc; ProtectHome protect_home; ProtectSystem protect_system; ProtectProc protect_proc;