From: Mike Yuan Date: Fri, 18 Apr 2025 19:55:27 +0000 (+0200) Subject: namespace-util: generalize namespace_type_supported() X-Git-Tag: v258-rc1~768^2~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=418082596cebd1f3d8eac9a0d73d6beada56e89b;p=thirdparty%2Fsystemd.git namespace-util: generalize namespace_type_supported() --- diff --git a/src/basic/namespace-util.c b/src/basic/namespace-util.c index b4ef5941fb6..e62737898b4 100644 --- a/src/basic/namespace-util.c +++ b/src/basic/namespace-util.c @@ -48,6 +48,13 @@ NamespaceType clone_flag_to_namespace_type(unsigned long clone_flag) { return _NAMESPACE_TYPE_INVALID; } +bool namespace_type_supported(NamespaceType type) { + assert(type >= 0 && type < _NAMESPACE_TYPE_MAX); + + const char *p = pid_namespace_path(0, type); + return access(p, F_OK) >= 0; +} + static int pidref_namespace_open_by_type_internal(const PidRef *pidref, NamespaceType type, bool *need_verify) { int r; diff --git a/src/basic/namespace-util.h b/src/basic/namespace-util.h index 0c227e5adf0..d7ac8156f94 100644 --- a/src/basic/namespace-util.h +++ b/src/basic/namespace-util.h @@ -28,6 +28,8 @@ extern const struct namespace_info { NamespaceType clone_flag_to_namespace_type(unsigned long clone_flag); +bool namespace_type_supported(NamespaceType type); + int pidref_namespace_open_by_type(const PidRef *pidref, NamespaceType type); int namespace_open_by_type(NamespaceType type); diff --git a/src/core/exec-invoke.c b/src/core/exec-invoke.c index 0bf6c836013..7b283eb485a 100644 --- a/src/core/exec-invoke.c +++ b/src/core/exec-invoke.c @@ -1820,7 +1820,7 @@ static int apply_protect_hostname(const ExecContext *c, const ExecParameters *p, if (c->protect_hostname == PROTECT_HOSTNAME_NO) return 0; - if (ns_type_supported(NAMESPACE_UTS)) { + if (namespace_type_supported(NAMESPACE_UTS)) { if (unshare(CLONE_NEWUTS) < 0) { if (!ERRNO_IS_NOT_SUPPORTED(errno) && !ERRNO_IS_PRIVILEGE(errno)) { *ret_exit_status = EXIT_NAMESPACE; @@ -4339,7 +4339,7 @@ static int setup_delegated_namespaces( * own user namespace). We need CAP_NET_ADMIN to be able to configure the loopback device in * the new network namespace. And if we don't have that, then we could only create a network * namespace without the ability to set up "lo". Hence gracefully skip things then. */ - if (ns_type_supported(NAMESPACE_NET) && have_effective_cap(CAP_NET_ADMIN) > 0) { + if (namespace_type_supported(NAMESPACE_NET) && have_effective_cap(CAP_NET_ADMIN) > 0) { r = setup_shareable_ns(runtime->shared->netns_storage_socket, CLONE_NEWNET); if (ERRNO_IS_NEG_PRIVILEGE(r)) log_exec_notice_errno(context, params, r, @@ -4361,7 +4361,7 @@ static int setup_delegated_namespaces( exec_namespace_is_delegated(context, params, have_cap_sys_admin, CLONE_NEWIPC) == delegate && runtime->shared && runtime->shared->ipcns_storage_socket[0] >= 0) { - if (ns_type_supported(NAMESPACE_IPC)) { + if (namespace_type_supported(NAMESPACE_IPC)) { r = setup_shareable_ns(runtime->shared->ipcns_storage_socket, CLONE_NEWIPC); if (ERRNO_IS_NEG_PRIVILEGE(r)) log_exec_warning_errno(context, params, r, diff --git a/src/core/execute.c b/src/core/execute.c index 6f4baa1fbfd..76ad7345ca0 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -243,7 +243,7 @@ ProtectControlGroups exec_get_protect_control_groups(const ExecContext *context) * use cgroup namespace, we ignore the setting and do not unshare the namespace. * ProtectControlGroups=private and strict get downgraded to no and yes respectively. This ensures * that strict always gets a read-only mount of /sys/fs/cgroup/. */ - if (needs_cgroup_namespace(context->protect_control_groups) && !ns_type_supported(NAMESPACE_CGROUP)) { + if (needs_cgroup_namespace(context->protect_control_groups) && !namespace_type_supported(NAMESPACE_CGROUP)) { if (context->protect_control_groups == PROTECT_CONTROL_GROUPS_PRIVATE) return PROTECT_CONTROL_GROUPS_NO; if (context->protect_control_groups == PROTECT_CONTROL_GROUPS_STRICT) @@ -273,7 +273,7 @@ bool exec_is_cgroup_mount_read_only(const ExecContext *context) { bool exec_needs_pid_namespace(const ExecContext *context) { assert(context); - return context->private_pids != PRIVATE_PIDS_NO && ns_type_supported(NAMESPACE_PID); + return context->private_pids != PRIVATE_PIDS_NO && namespace_type_supported(NAMESPACE_PID); } bool exec_needs_mount_namespace( diff --git a/src/core/namespace.c b/src/core/namespace.c index 01d3c977d41..efdd93ddf9d 100644 --- a/src/core/namespace.c +++ b/src/core/namespace.c @@ -3263,17 +3263,6 @@ int open_shareable_ns_path(int ns_storage_socket[static 2], const char *path, un return 1; } -bool ns_type_supported(NamespaceType type) { - const char *t, *ns_proc; - - t = namespace_type_to_string(type); - if (!t) /* Don't know how to translate this? Then it's not supported */ - return false; - - ns_proc = strjoina("/proc/self/ns/", t); - return access(ns_proc, F_OK) == 0; -} - static const char *const protect_home_table[_PROTECT_HOME_MAX] = { [PROTECT_HOME_NO] = "no", [PROTECT_HOME_YES] = "yes", @@ -3309,19 +3298,6 @@ static const char *const protect_control_groups_table[_PROTECT_CONTROL_GROUPS_MA DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(protect_control_groups, ProtectControlGroups, PROTECT_CONTROL_GROUPS_YES); -static const char* const namespace_type_table[] = { - [NAMESPACE_MOUNT] = "mnt", - [NAMESPACE_CGROUP] = "cgroup", - [NAMESPACE_UTS] = "uts", - [NAMESPACE_IPC] = "ipc", - [NAMESPACE_USER] = "user", - [NAMESPACE_PID] = "pid", - [NAMESPACE_NET] = "net", - [NAMESPACE_TIME] = "time", -}; - -DEFINE_STRING_TABLE_LOOKUP(namespace_type, NamespaceType); - static const char* const protect_proc_table[_PROTECT_PROC_MAX] = { [PROTECT_PROC_DEFAULT] = "default", [PROTECT_PROC_NOACCESS] = "noaccess", diff --git a/src/core/namespace.h b/src/core/namespace.h index 069cdb831ab..0ff9b4d7309 100644 --- a/src/core/namespace.h +++ b/src/core/namespace.h @@ -258,8 +258,3 @@ int temporary_filesystem_add(TemporaryFileSystem **t, size_t *n, MountImage* mount_image_free_many(MountImage *m, size_t *n); int mount_image_add(MountImage **m, size_t *n, const MountImage *item); - -const char* namespace_type_to_string(NamespaceType t) _const_; -NamespaceType namespace_type_from_string(const char *s) _pure_; - -bool ns_type_supported(NamespaceType type); diff --git a/src/core/socket.c b/src/core/socket.c index e7e8584d81d..861aaba3d44 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -1570,7 +1570,7 @@ static int socket_address_listen_in_cgroup( s->exec_runtime->shared && s->exec_runtime->shared->netns_storage_socket[0] >= 0) { - if (ns_type_supported(NAMESPACE_NET)) { + if (namespace_type_supported(NAMESPACE_NET)) { r = setup_shareable_ns(s->exec_runtime->shared->netns_storage_socket, CLONE_NEWNET); if (r < 0) { log_unit_error_errno(UNIT(s), r, "Failed to join network namespace: %m"); diff --git a/src/test/test-tables.c b/src/test/test-tables.c index 142ddc48328..1896391beeb 100644 --- a/src/test/test-tables.c +++ b/src/test/test-tables.c @@ -82,7 +82,6 @@ int main(int argc, char **argv) { test_table(mount_result, MOUNT_RESULT); test_table(mount_state, MOUNT_STATE); test_table(name_policy, NAMEPOLICY); - test_table(namespace_type, NAMESPACE_TYPE); test_table(notify_access, NOTIFY_ACCESS); test_table(notify_state, NOTIFY_STATE); test_table(output_mode, OUTPUT_MODE);