]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
ns: move ns type into struct ns_common
authorChristian Brauner <brauner@kernel.org>
Wed, 24 Sep 2025 11:33:59 +0000 (13:33 +0200)
committerChristian Brauner <brauner@kernel.org>
Thu, 25 Sep 2025 07:23:54 +0000 (09:23 +0200)
It's misplaced in struct proc_ns_operations and ns->ops might be NULL if
the namespace is compiled out but we still want to know the type of the
namespace for the initial namespace struct.

Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Christian Brauner <brauner@kernel.org>
19 files changed:
fs/namespace.c
fs/nsfs.c
include/linux/ns_common.h
include/linux/proc_ns.h
init/version-timestamp.c
ipc/msgutil.c
ipc/namespace.c
kernel/cgroup/cgroup.c
kernel/cgroup/namespace.c
kernel/nscommon.c
kernel/nsproxy.c
kernel/nstree.c
kernel/pid.c
kernel/pid_namespace.c
kernel/time/namespace.c
kernel/user.c
kernel/user_namespace.c
kernel/utsname.c
net/core/net_namespace.c

index d65917ec5544fe382925d918be93da8565340281..01334d5038a2711519e7f83a9e7bd195eeca7e89 100644 (file)
@@ -4927,7 +4927,7 @@ static int build_mount_idmapped(const struct mount_attr *attr, size_t usize,
                return -EINVAL;
 
        ns = get_proc_ns(file_inode(fd_file(f)));
-       if (ns->ops->type != CLONE_NEWUSER)
+       if (ns->ns_type != CLONE_NEWUSER)
                return -EINVAL;
 
        /*
@@ -5830,7 +5830,7 @@ static struct mnt_namespace *grab_requested_mnt_ns(const struct mnt_id_req *kreq
                        return ERR_PTR(-EINVAL);
 
                ns = get_proc_ns(file_inode(fd_file(f)));
-               if (ns->ops->type != CLONE_NEWNS)
+               if (ns->ns_type != CLONE_NEWNS)
                        return ERR_PTR(-EINVAL);
 
                mnt_ns = to_mnt_ns(ns);
@@ -6016,6 +6016,7 @@ struct mnt_namespace init_mnt_ns = {
        .ns.ops         = &mntns_operations,
        .user_ns        = &init_user_ns,
        .ns.__ns_ref    = REFCOUNT_INIT(1),
+       .ns.ns_type     = ns_common_type(&init_mnt_ns),
        .passive        = REFCOUNT_INIT(1),
        .mounts         = RB_ROOT,
        .poll           = __WAIT_QUEUE_HEAD_INITIALIZER(init_mnt_ns.poll),
@@ -6333,7 +6334,6 @@ static struct user_namespace *mntns_owner(struct ns_common *ns)
 
 const struct proc_ns_operations mntns_operations = {
        .name           = "mnt",
-       .type           = CLONE_NEWNS,
        .get            = mntns_get,
        .put            = mntns_put,
        .install        = mntns_install,
index dc0a4404b9718ebd19a0138f33ecee9bb3f82a5d..e7fd8a790aaa4b4b46d422e99eedc8f24def865c 100644 (file)
--- a/fs/nsfs.c
+++ b/fs/nsfs.c
@@ -219,9 +219,9 @@ static long ns_ioctl(struct file *filp, unsigned int ioctl,
                        return -EINVAL;
                return open_related_ns(ns, ns->ops->get_parent);
        case NS_GET_NSTYPE:
-               return ns->ops->type;
+               return ns->ns_type;
        case NS_GET_OWNER_UID:
-               if (ns->ops->type != CLONE_NEWUSER)
+               if (ns->ns_type != CLONE_NEWUSER)
                        return -EINVAL;
                user_ns = container_of(ns, struct user_namespace, ns);
                argp = (uid_t __user *) arg;
@@ -234,7 +234,7 @@ static long ns_ioctl(struct file *filp, unsigned int ioctl,
        case NS_GET_PID_IN_PIDNS:
                fallthrough;
        case NS_GET_TGID_IN_PIDNS: {
-               if (ns->ops->type != CLONE_NEWPID)
+               if (ns->ns_type != CLONE_NEWPID)
                        return -EINVAL;
 
                ret = -ESRCH;
@@ -273,7 +273,7 @@ static long ns_ioctl(struct file *filp, unsigned int ioctl,
                return ret;
        }
        case NS_GET_MNTNS_ID:
-               if (ns->ops->type != CLONE_NEWNS)
+               if (ns->ns_type != CLONE_NEWNS)
                        return -EINVAL;
                fallthrough;
        case NS_GET_ID: {
@@ -293,7 +293,7 @@ static long ns_ioctl(struct file *filp, unsigned int ioctl,
                struct mnt_ns_info __user *uinfo = (struct mnt_ns_info __user *)arg;
                size_t usize = _IOC_SIZE(ioctl);
 
-               if (ns->ops->type != CLONE_NEWNS)
+               if (ns->ns_type != CLONE_NEWNS)
                        return -EINVAL;
 
                if (!uinfo)
@@ -314,7 +314,7 @@ static long ns_ioctl(struct file *filp, unsigned int ioctl,
                struct file *f __free(fput) = NULL;
                size_t usize = _IOC_SIZE(ioctl);
 
-               if (ns->ops->type != CLONE_NEWNS)
+               if (ns->ns_type != CLONE_NEWNS)
                        return -EINVAL;
 
                if (usize < MNT_NS_INFO_SIZE_VER0)
@@ -453,7 +453,7 @@ static int nsfs_encode_fh(struct inode *inode, u32 *fh, int *max_len,
        }
 
        fid->ns_id      = ns->ns_id;
-       fid->ns_type    = ns->ops->type;
+       fid->ns_type    = ns->ns_type;
        fid->ns_inum    = inode->i_ino;
        return FILEID_NSFS;
 }
@@ -489,14 +489,14 @@ static struct dentry *nsfs_fh_to_dentry(struct super_block *sb, struct fid *fh,
                        return NULL;
 
                VFS_WARN_ON_ONCE(ns->ns_id != fid->ns_id);
-               VFS_WARN_ON_ONCE(ns->ops->type != fid->ns_type);
+               VFS_WARN_ON_ONCE(ns->ns_type != fid->ns_type);
                VFS_WARN_ON_ONCE(ns->inum != fid->ns_inum);
 
                if (!__ns_ref_get(ns))
                        return NULL;
        }
 
-       switch (ns->ops->type) {
+       switch (ns->ns_type) {
 #ifdef CONFIG_CGROUPS
        case CLONE_NEWCGROUP:
                if (!current_in_namespace(to_cg_ns(ns)))
index 56492cd9ff8d43a837d55fd13bf2452f6f988777..f5b68b8abb5433fe78b5a2e29cbd3fbd3dcc5c97 100644 (file)
@@ -4,6 +4,7 @@
 
 #include <linux/refcount.h>
 #include <linux/rbtree.h>
+#include <uapi/linux/sched.h>
 
 struct proc_ns_operations;
 
@@ -37,6 +38,7 @@ extern const struct proc_ns_operations timens_operations;
 extern const struct proc_ns_operations timens_for_children_operations;
 
 struct ns_common {
+       u32 ns_type;
        struct dentry *stashed;
        const struct proc_ns_operations *ops;
        unsigned int inum;
@@ -51,7 +53,7 @@ struct ns_common {
        };
 };
 
-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);
 void __ns_common_free(struct ns_common *ns);
 
 #define to_ns_common(__ns)                                    \
@@ -106,10 +108,28 @@ void __ns_common_free(struct ns_common *ns);
                struct user_namespace *:   (IS_ENABLED(CONFIG_USER_NS) ? &userns_operations   : NULL), \
                struct uts_namespace *:    (IS_ENABLED(CONFIG_UTS_NS)  ? &utsns_operations    : NULL))
 
-#define ns_common_init(__ns) \
-       __ns_common_init(to_ns_common(__ns), to_ns_operations(__ns), (((__ns) == ns_init_ns(__ns)) ? ns_init_inum(__ns) : 0))
-
-#define ns_common_init_inum(__ns, __inum) __ns_common_init(to_ns_common(__ns), to_ns_operations(__ns), __inum)
+#define ns_common_type(__ns)                                \
+       _Generic((__ns),                                    \
+               struct cgroup_namespace *: CLONE_NEWCGROUP, \
+               struct ipc_namespace *:    CLONE_NEWIPC,    \
+               struct mnt_namespace *:    CLONE_NEWNS,     \
+               struct net *:              CLONE_NEWNET,    \
+               struct pid_namespace *:    CLONE_NEWPID,    \
+               struct time_namespace *:   CLONE_NEWTIME,   \
+               struct user_namespace *:   CLONE_NEWUSER,   \
+               struct uts_namespace *:    CLONE_NEWUTS)
+
+#define ns_common_init(__ns)                     \
+       __ns_common_init(to_ns_common(__ns),     \
+                        ns_common_type(__ns),   \
+                        to_ns_operations(__ns), \
+                        (((__ns) == ns_init_ns(__ns)) ? ns_init_inum(__ns) : 0))
+
+#define ns_common_init_inum(__ns, __inum)        \
+       __ns_common_init(to_ns_common(__ns),     \
+                        ns_common_type(__ns),   \
+                        to_ns_operations(__ns), \
+                        __inum)
 
 #define ns_common_free(__ns) __ns_common_free(to_ns_common((__ns)))
 
index 08016f6e0e6fb1ce71ecc4f689cd0ffe48e723fe..e81b8e596e4f194fde4a60843fb95b228d4898d1 100644 (file)
@@ -17,7 +17,6 @@ struct inode;
 struct proc_ns_operations {
        const char *name;
        const char *real_ns_name;
-       int type;
        struct ns_common *(*get)(struct task_struct *task);
        void (*put)(struct ns_common *ns);
        int (*install)(struct nsset *nsset, struct ns_common *ns);
index 376b7c856d4d037b27cb3e4451f2a50087d0a229..d071835121c2c452a7a57068157ec02e7517e100 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/utsname.h>
 
 struct uts_namespace init_uts_ns = {
+       .ns.ns_type = ns_common_type(&init_uts_ns),
        .ns.__ns_ref = REFCOUNT_INIT(2),
        .name = {
                .sysname        = UTS_SYSNAME,
index dca6c8ec8f5ff90d7ef80dc6fb2cd1c748f833d6..7a03f6d03de3adf7eca26d5cc6bba2580e7d5d3f 100644 (file)
@@ -33,6 +33,7 @@ struct ipc_namespace init_ipc_ns = {
 #ifdef CONFIG_IPC_NS
        .ns.ops = &ipcns_operations,
 #endif
+       .ns.ns_type = ns_common_type(&init_ipc_ns),
 };
 
 struct msg_msgseg {
index d89dfd718d2b1263c9dbe429acd437d003446c88..76abac74a5c3bb79b6b622f617a2941f13e58c2d 100644 (file)
@@ -248,7 +248,6 @@ static struct user_namespace *ipcns_owner(struct ns_common *ns)
 
 const struct proc_ns_operations ipcns_operations = {
        .name           = "ipc",
-       .type           = CLONE_NEWIPC,
        .get            = ipcns_get,
        .put            = ipcns_put,
        .install        = ipcns_install,
index 245b43ff2fa481abf232c3fae01ccbec01c2bc97..9b75102e81cb9c0a6be1cd80013f04bcfc5fec39 100644 (file)
@@ -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;
index 04c98338ac08d1ab787c11006d9a8b548c23856f..241ca05f07c81c01d533168c44c849e7ce7a1a8a 100644 (file)
@@ -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,
index 3cef89ddef41a341d0983df766a8cea95d91ee25..92c9df1e877413d56ced3ab2e4e97fac5822e9d9 100644 (file)
@@ -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);
@@ -52,12 +52,13 @@ static void ns_debug(struct ns_common *ns, const struct proc_ns_operations *ops)
 }
 #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);
 
index 5f31fdff8a38f5d932df1ed243e88497ea9b2fea..8d62449237b6fbe85660db7db893a049fb41fcf2 100644 (file)
@@ -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 {
index ecc88b013eff2f4c1eecb7b7c506e2bc7fa346a9..b24a320a11a683e7b3645677fbdb06ab72ce8e87 100644 (file)
@@ -106,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);
        /*
@@ -128,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);
@@ -197,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);
 }
@@ -225,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);
 }
index 7e8c66e0bf676f7b9d042c987302abd9e32686ba..0c2dcddb317a307547ed834234af798c244acc09 100644 (file)
@@ -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);
 
index a262a3f19443212292d86eeb63f45c4a4ed2f962..f5b222c8ac39ad4b96789f3c3a7076f9a69f60f0 100644 (file)
@@ -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,
index 9f26e61be044f31560e68286ade3ec2580508370..530cf99c221286cf68c340d70aeafea33b541295 100644 (file)
@@ -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),
index b2a53674d506f805339c7e310cf32bc6756a139e..0163665914c97c0d39d9e38a31668483a79cafb4 100644 (file)
@@ -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,
index e1559e8a8a02c5abe47bbe2f7fd46ddf5db30e6e..03cb63883d041a3c82dc89357af307bd41dcbfff 100644 (file)
@@ -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,
index 00001592ad134b078b17a39e4e5a8f5a60217d0b..a8cdc84648ee790f0643ca05fbc66b9e6250f580 100644 (file)
@@ -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,
index bdea7d5fac56084921b1cca95b9254fa837df1f4..dfe84bd35f98115ee77e5872ed3456c3d185ccc9 100644 (file)
@@ -1543,7 +1543,6 @@ static struct user_namespace *netns_owner(struct ns_common *ns)
 
 const struct proc_ns_operations netns_operations = {
        .name           = "net",
-       .type           = CLONE_NEWNET,
        .get            = netns_get,
        .put            = netns_put,
        .install        = netns_install,