aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorChristian Brauner <brauner@kernel.org>2025-09-25 09:22:09 +0200
committerChristian Brauner <brauner@kernel.org>2025-09-25 09:23:55 +0200
commit6e65f4e8fc5b02f7a60ebb5b1b83772df0b86663 (patch)
treeb76db4a01798af39da02bf1581beaca1a9302f97 /kernel
parentMerge patch series "ns: minor tweaks" (diff)
parentns: drop assert (diff)
downloadlinux-6e65f4e8fc5b02f7a60ebb5b1b83772df0b86663.tar.gz
linux-6e65f4e8fc5b02f7a60ebb5b1b83772df0b86663.zip
Merge patch series "ns: tweak ns common handling"
Christian Brauner <brauner@kernel.org> says: This contains three minor tweaks for namespace handling: * Make struct ns_tree private. There's no need for anything to access that directly. * Drop a debug assert that would trigger in conditions that are benign. * Move the type of the namespace out of struct proc_ns_operations and into struct ns_common. This eliminates a pointer dereference and also allows assertions to work when the namespace type is disabled and the operations field set to NULL. * patches from https://lore.kernel.org/20250924-work-namespaces-fixes-v1-0-8fb682c8678e@kernel.org: ns: drop assert ns: move ns type into struct ns_common nstree: make struct ns_tree private Signed-off-by: Christian Brauner <brauner@kernel.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/cgroup/cgroup.c1
-rw-r--r--kernel/cgroup/namespace.c1
-rw-r--r--kernel/nscommon.c7
-rw-r--r--kernel/nsproxy.c4
-rw-r--r--kernel/nstree.c22
-rw-r--r--kernel/pid.c1
-rw-r--r--kernel/pid_namespace.c2
-rw-r--r--kernel/time/namespace.c3
-rw-r--r--kernel/user.c1
-rw-r--r--kernel/user_namespace.c1
-rw-r--r--kernel/utsname.c1
11 files changed, 27 insertions, 17 deletions
diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c
index 245b43ff2fa4..9b75102e81cb 100644
--- a/kernel/cgroup/cgroup.c
+++ b/kernel/cgroup/cgroup.c
@@ -224,6 +224,7 @@ struct cgroup_namespace init_cgroup_ns = {
.ns.ops = &cgroupns_operations,
.ns.inum = ns_init_inum(&init_cgroup_ns),
.root_cset = &init_css_set,
+ .ns.ns_type = ns_common_type(&init_cgroup_ns),
};
static struct file_system_type cgroup2_fs_type;
diff --git a/kernel/cgroup/namespace.c b/kernel/cgroup/namespace.c
index 04c98338ac08..241ca05f07c8 100644
--- a/kernel/cgroup/namespace.c
+++ b/kernel/cgroup/namespace.c
@@ -137,7 +137,6 @@ static struct user_namespace *cgroupns_owner(struct ns_common *ns)
const struct proc_ns_operations cgroupns_operations = {
.name = "cgroup",
- .type = CLONE_NEWCGROUP,
.get = cgroupns_get,
.put = cgroupns_put,
.install = cgroupns_install,
diff --git a/kernel/nscommon.c b/kernel/nscommon.c
index 3cef89ddef41..c1fb2bad6d72 100644
--- a/kernel/nscommon.c
+++ b/kernel/nscommon.c
@@ -7,7 +7,7 @@
#ifdef CONFIG_DEBUG_VFS
static void ns_debug(struct ns_common *ns, const struct proc_ns_operations *ops)
{
- switch (ns->ops->type) {
+ switch (ns->ns_type) {
#ifdef CONFIG_CGROUPS
case CLONE_NEWCGROUP:
VFS_WARN_ON_ONCE(ops != &cgroupns_operations);
@@ -46,18 +46,17 @@ static void ns_debug(struct ns_common *ns, const struct proc_ns_operations *ops)
VFS_WARN_ON_ONCE(ops != &utsns_operations);
break;
#endif
- default:
- VFS_WARN_ON_ONCE(true);
}
}
#endif
-int __ns_common_init(struct ns_common *ns, const struct proc_ns_operations *ops, int inum)
+int __ns_common_init(struct ns_common *ns, u32 ns_type, const struct proc_ns_operations *ops, int inum)
{
refcount_set(&ns->__ns_ref, 1);
ns->stashed = NULL;
ns->ops = ops;
ns->ns_id = 0;
+ ns->ns_type = ns_type;
RB_CLEAR_NODE(&ns->ns_tree_node);
INIT_LIST_HEAD(&ns->ns_list_node);
diff --git a/kernel/nsproxy.c b/kernel/nsproxy.c
index 5f31fdff8a38..8d62449237b6 100644
--- a/kernel/nsproxy.c
+++ b/kernel/nsproxy.c
@@ -545,9 +545,9 @@ SYSCALL_DEFINE2(setns, int, fd, int, flags)
if (proc_ns_file(fd_file(f))) {
ns = get_proc_ns(file_inode(fd_file(f)));
- if (flags && (ns->ops->type != flags))
+ if (flags && (ns->ns_type != flags))
err = -EINVAL;
- flags = ns->ops->type;
+ flags = ns->ns_type;
} else if (!IS_ERR(pidfd_pid(fd_file(f)))) {
err = check_setns_flags(flags);
} else {
diff --git a/kernel/nstree.c b/kernel/nstree.c
index bbe8bedc924c..b24a320a11a6 100644
--- a/kernel/nstree.c
+++ b/kernel/nstree.c
@@ -4,6 +4,20 @@
#include <linux/proc_ns.h>
#include <linux/vfsdebug.h>
+/**
+ * struct ns_tree - Namespace tree
+ * @ns_tree: Rbtree of namespaces of a particular type
+ * @ns_list: Sequentially walkable list of all namespaces of this type
+ * @ns_tree_lock: Seqlock to protect the tree and list
+ * @type: type of namespaces in this tree
+ */
+struct ns_tree {
+ struct rb_root ns_tree;
+ struct list_head ns_list;
+ seqlock_t ns_tree_lock;
+ int type;
+};
+
struct ns_tree mnt_ns_tree = {
.ns_tree = RB_ROOT,
.ns_list = LIST_HEAD_INIT(mnt_ns_tree.ns_list),
@@ -92,7 +106,7 @@ void __ns_tree_add_raw(struct ns_common *ns, struct ns_tree *ns_tree)
write_seqlock(&ns_tree->ns_tree_lock);
- VFS_WARN_ON_ONCE(ns->ops->type != ns_tree->type);
+ VFS_WARN_ON_ONCE(ns->ns_type != ns_tree->type);
node = rb_find_add_rcu(&ns->ns_tree_node, &ns_tree->ns_tree, ns_cmp);
/*
@@ -114,7 +128,7 @@ void __ns_tree_remove(struct ns_common *ns, struct ns_tree *ns_tree)
{
VFS_WARN_ON_ONCE(RB_EMPTY_NODE(&ns->ns_tree_node));
VFS_WARN_ON_ONCE(list_empty(&ns->ns_list_node));
- VFS_WARN_ON_ONCE(ns->ops->type != ns_tree->type);
+ VFS_WARN_ON_ONCE(ns->ns_type != ns_tree->type);
write_seqlock(&ns_tree->ns_tree_lock);
rb_erase(&ns->ns_tree_node, &ns_tree->ns_tree);
@@ -183,7 +197,7 @@ struct ns_common *ns_tree_lookup_rcu(u64 ns_id, int ns_type)
if (!node)
return NULL;
- VFS_WARN_ON_ONCE(node_to_ns(node)->ops->type != ns_type);
+ VFS_WARN_ON_ONCE(node_to_ns(node)->ns_type != ns_type);
return node_to_ns(node);
}
@@ -211,7 +225,7 @@ struct ns_common *__ns_tree_adjoined_rcu(struct ns_common *ns,
if (list_is_head(list, &ns_tree->ns_list))
return ERR_PTR(-ENOENT);
- VFS_WARN_ON_ONCE(list_entry_rcu(list, struct ns_common, ns_list_node)->ops->type != ns_tree->type);
+ VFS_WARN_ON_ONCE(list_entry_rcu(list, struct ns_common, ns_list_node)->ns_type != ns_tree->type);
return list_entry_rcu(list, struct ns_common, ns_list_node);
}
diff --git a/kernel/pid.c b/kernel/pid.c
index 7e8c66e0bf67..0c2dcddb317a 100644
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -85,6 +85,7 @@ struct pid_namespace init_pid_ns = {
#if defined(CONFIG_SYSCTL) && defined(CONFIG_MEMFD_CREATE)
.memfd_noexec_scope = MEMFD_NOEXEC_SCOPE_EXEC,
#endif
+ .ns.ns_type = ns_common_type(&init_pid_ns),
};
EXPORT_SYMBOL_GPL(init_pid_ns);
diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c
index a262a3f19443..f5b222c8ac39 100644
--- a/kernel/pid_namespace.c
+++ b/kernel/pid_namespace.c
@@ -443,7 +443,6 @@ static struct user_namespace *pidns_owner(struct ns_common *ns)
const struct proc_ns_operations pidns_operations = {
.name = "pid",
- .type = CLONE_NEWPID,
.get = pidns_get,
.put = pidns_put,
.install = pidns_install,
@@ -454,7 +453,6 @@ const struct proc_ns_operations pidns_operations = {
const struct proc_ns_operations pidns_for_children_operations = {
.name = "pid_for_children",
.real_ns_name = "pid",
- .type = CLONE_NEWPID,
.get = pidns_for_children_get,
.put = pidns_put,
.install = pidns_install,
diff --git a/kernel/time/namespace.c b/kernel/time/namespace.c
index 9f26e61be044..530cf99c2212 100644
--- a/kernel/time/namespace.c
+++ b/kernel/time/namespace.c
@@ -462,7 +462,6 @@ out:
const struct proc_ns_operations timens_operations = {
.name = "time",
- .type = CLONE_NEWTIME,
.get = timens_get,
.put = timens_put,
.install = timens_install,
@@ -472,7 +471,6 @@ const struct proc_ns_operations timens_operations = {
const struct proc_ns_operations timens_for_children_operations = {
.name = "time_for_children",
.real_ns_name = "time",
- .type = CLONE_NEWTIME,
.get = timens_for_children_get,
.put = timens_put,
.install = timens_install,
@@ -480,6 +478,7 @@ const struct proc_ns_operations timens_for_children_operations = {
};
struct time_namespace init_time_ns = {
+ .ns.ns_type = ns_common_type(&init_time_ns),
.ns.__ns_ref = REFCOUNT_INIT(3),
.user_ns = &init_user_ns,
.ns.inum = ns_init_inum(&init_time_ns),
diff --git a/kernel/user.c b/kernel/user.c
index b2a53674d506..0163665914c9 100644
--- a/kernel/user.c
+++ b/kernel/user.c
@@ -65,6 +65,7 @@ struct user_namespace init_user_ns = {
.nr_extents = 1,
},
},
+ .ns.ns_type = ns_common_type(&init_user_ns),
.ns.__ns_ref = REFCOUNT_INIT(3),
.owner = GLOBAL_ROOT_UID,
.group = GLOBAL_ROOT_GID,
diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
index e1559e8a8a02..03cb63883d04 100644
--- a/kernel/user_namespace.c
+++ b/kernel/user_namespace.c
@@ -1400,7 +1400,6 @@ static struct user_namespace *userns_owner(struct ns_common *ns)
const struct proc_ns_operations userns_operations = {
.name = "user",
- .type = CLONE_NEWUSER,
.get = userns_get,
.put = userns_put,
.install = userns_install,
diff --git a/kernel/utsname.c b/kernel/utsname.c
index 00001592ad13..a8cdc84648ee 100644
--- a/kernel/utsname.c
+++ b/kernel/utsname.c
@@ -146,7 +146,6 @@ static struct user_namespace *utsns_owner(struct ns_common *ns)
const struct proc_ns_operations utsns_operations = {
.name = "uts",
- .type = CLONE_NEWUTS,
.get = utsns_get,
.put = utsns_put,
.install = utsns_install,