Skip to content

Commit 6e65f4e

Browse files
committed
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>
2 parents d969328 + af07560 commit 6e65f4e

20 files changed

Lines changed: 66 additions & 50 deletions

fs/namespace.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4927,7 +4927,7 @@ static int build_mount_idmapped(const struct mount_attr *attr, size_t usize,
49274927
return -EINVAL;
49284928

49294929
ns = get_proc_ns(file_inode(fd_file(f)));
4930-
if (ns->ops->type != CLONE_NEWUSER)
4930+
if (ns->ns_type != CLONE_NEWUSER)
49314931
return -EINVAL;
49324932

49334933
/*
@@ -5830,7 +5830,7 @@ static struct mnt_namespace *grab_requested_mnt_ns(const struct mnt_id_req *kreq
58305830
return ERR_PTR(-EINVAL);
58315831

58325832
ns = get_proc_ns(file_inode(fd_file(f)));
5833-
if (ns->ops->type != CLONE_NEWNS)
5833+
if (ns->ns_type != CLONE_NEWNS)
58345834
return ERR_PTR(-EINVAL);
58355835

58365836
mnt_ns = to_mnt_ns(ns);
@@ -6016,6 +6016,7 @@ struct mnt_namespace init_mnt_ns = {
60166016
.ns.ops = &mntns_operations,
60176017
.user_ns = &init_user_ns,
60186018
.ns.__ns_ref = REFCOUNT_INIT(1),
6019+
.ns.ns_type = ns_common_type(&init_mnt_ns),
60196020
.passive = REFCOUNT_INIT(1),
60206021
.mounts = RB_ROOT,
60216022
.poll = __WAIT_QUEUE_HEAD_INITIALIZER(init_mnt_ns.poll),
@@ -6333,7 +6334,6 @@ static struct user_namespace *mntns_owner(struct ns_common *ns)
63336334

63346335
const struct proc_ns_operations mntns_operations = {
63356336
.name = "mnt",
6336-
.type = CLONE_NEWNS,
63376337
.get = mntns_get,
63386338
.put = mntns_put,
63396339
.install = mntns_install,

fs/nsfs.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -219,9 +219,9 @@ static long ns_ioctl(struct file *filp, unsigned int ioctl,
219219
return -EINVAL;
220220
return open_related_ns(ns, ns->ops->get_parent);
221221
case NS_GET_NSTYPE:
222-
return ns->ops->type;
222+
return ns->ns_type;
223223
case NS_GET_OWNER_UID:
224-
if (ns->ops->type != CLONE_NEWUSER)
224+
if (ns->ns_type != CLONE_NEWUSER)
225225
return -EINVAL;
226226
user_ns = container_of(ns, struct user_namespace, ns);
227227
argp = (uid_t __user *) arg;
@@ -234,7 +234,7 @@ static long ns_ioctl(struct file *filp, unsigned int ioctl,
234234
case NS_GET_PID_IN_PIDNS:
235235
fallthrough;
236236
case NS_GET_TGID_IN_PIDNS: {
237-
if (ns->ops->type != CLONE_NEWPID)
237+
if (ns->ns_type != CLONE_NEWPID)
238238
return -EINVAL;
239239

240240
ret = -ESRCH;
@@ -273,7 +273,7 @@ static long ns_ioctl(struct file *filp, unsigned int ioctl,
273273
return ret;
274274
}
275275
case NS_GET_MNTNS_ID:
276-
if (ns->ops->type != CLONE_NEWNS)
276+
if (ns->ns_type != CLONE_NEWNS)
277277
return -EINVAL;
278278
fallthrough;
279279
case NS_GET_ID: {
@@ -293,7 +293,7 @@ static long ns_ioctl(struct file *filp, unsigned int ioctl,
293293
struct mnt_ns_info __user *uinfo = (struct mnt_ns_info __user *)arg;
294294
size_t usize = _IOC_SIZE(ioctl);
295295

296-
if (ns->ops->type != CLONE_NEWNS)
296+
if (ns->ns_type != CLONE_NEWNS)
297297
return -EINVAL;
298298

299299
if (!uinfo)
@@ -314,7 +314,7 @@ static long ns_ioctl(struct file *filp, unsigned int ioctl,
314314
struct file *f __free(fput) = NULL;
315315
size_t usize = _IOC_SIZE(ioctl);
316316

317-
if (ns->ops->type != CLONE_NEWNS)
317+
if (ns->ns_type != CLONE_NEWNS)
318318
return -EINVAL;
319319

320320
if (usize < MNT_NS_INFO_SIZE_VER0)
@@ -453,7 +453,7 @@ static int nsfs_encode_fh(struct inode *inode, u32 *fh, int *max_len,
453453
}
454454

455455
fid->ns_id = ns->ns_id;
456-
fid->ns_type = ns->ops->type;
456+
fid->ns_type = ns->ns_type;
457457
fid->ns_inum = inode->i_ino;
458458
return FILEID_NSFS;
459459
}
@@ -489,14 +489,14 @@ static struct dentry *nsfs_fh_to_dentry(struct super_block *sb, struct fid *fh,
489489
return NULL;
490490

491491
VFS_WARN_ON_ONCE(ns->ns_id != fid->ns_id);
492-
VFS_WARN_ON_ONCE(ns->ops->type != fid->ns_type);
492+
VFS_WARN_ON_ONCE(ns->ns_type != fid->ns_type);
493493
VFS_WARN_ON_ONCE(ns->inum != fid->ns_inum);
494494

495495
if (!__ns_ref_get(ns))
496496
return NULL;
497497
}
498498

499-
switch (ns->ops->type) {
499+
switch (ns->ns_type) {
500500
#ifdef CONFIG_CGROUPS
501501
case CLONE_NEWCGROUP:
502502
if (!current_in_namespace(to_cg_ns(ns)))

include/linux/ns_common.h

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#include <linux/refcount.h>
66
#include <linux/rbtree.h>
7+
#include <uapi/linux/sched.h>
78

89
struct proc_ns_operations;
910

@@ -37,6 +38,7 @@ extern const struct proc_ns_operations timens_operations;
3738
extern const struct proc_ns_operations timens_for_children_operations;
3839

3940
struct ns_common {
41+
u32 ns_type;
4042
struct dentry *stashed;
4143
const struct proc_ns_operations *ops;
4244
unsigned int inum;
@@ -51,7 +53,7 @@ struct ns_common {
5153
};
5254
};
5355

54-
int __ns_common_init(struct ns_common *ns, const struct proc_ns_operations *ops, int inum);
56+
int __ns_common_init(struct ns_common *ns, u32 ns_type, const struct proc_ns_operations *ops, int inum);
5557
void __ns_common_free(struct ns_common *ns);
5658

5759
#define to_ns_common(__ns) \
@@ -106,10 +108,28 @@ void __ns_common_free(struct ns_common *ns);
106108
struct user_namespace *: (IS_ENABLED(CONFIG_USER_NS) ? &userns_operations : NULL), \
107109
struct uts_namespace *: (IS_ENABLED(CONFIG_UTS_NS) ? &utsns_operations : NULL))
108110

109-
#define ns_common_init(__ns) \
110-
__ns_common_init(to_ns_common(__ns), to_ns_operations(__ns), (((__ns) == ns_init_ns(__ns)) ? ns_init_inum(__ns) : 0))
111-
112-
#define ns_common_init_inum(__ns, __inum) __ns_common_init(to_ns_common(__ns), to_ns_operations(__ns), __inum)
111+
#define ns_common_type(__ns) \
112+
_Generic((__ns), \
113+
struct cgroup_namespace *: CLONE_NEWCGROUP, \
114+
struct ipc_namespace *: CLONE_NEWIPC, \
115+
struct mnt_namespace *: CLONE_NEWNS, \
116+
struct net *: CLONE_NEWNET, \
117+
struct pid_namespace *: CLONE_NEWPID, \
118+
struct time_namespace *: CLONE_NEWTIME, \
119+
struct user_namespace *: CLONE_NEWUSER, \
120+
struct uts_namespace *: CLONE_NEWUTS)
121+
122+
#define ns_common_init(__ns) \
123+
__ns_common_init(to_ns_common(__ns), \
124+
ns_common_type(__ns), \
125+
to_ns_operations(__ns), \
126+
(((__ns) == ns_init_ns(__ns)) ? ns_init_inum(__ns) : 0))
127+
128+
#define ns_common_init_inum(__ns, __inum) \
129+
__ns_common_init(to_ns_common(__ns), \
130+
ns_common_type(__ns), \
131+
to_ns_operations(__ns), \
132+
__inum)
113133

114134
#define ns_common_free(__ns) __ns_common_free(to_ns_common((__ns)))
115135

include/linux/nstree.h

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,6 @@
99
#include <linux/rculist.h>
1010
#include <linux/cookie.h>
1111

12-
/**
13-
* struct ns_tree - Namespace tree
14-
* @ns_tree: Rbtree of namespaces of a particular type
15-
* @ns_list: Sequentially walkable list of all namespaces of this type
16-
* @ns_tree_lock: Seqlock to protect the tree and list
17-
*/
18-
struct ns_tree {
19-
struct rb_root ns_tree;
20-
struct list_head ns_list;
21-
seqlock_t ns_tree_lock;
22-
int type;
23-
};
24-
2512
extern struct ns_tree cgroup_ns_tree;
2613
extern struct ns_tree ipc_ns_tree;
2714
extern struct ns_tree mnt_ns_tree;

include/linux/proc_ns.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ struct inode;
1717
struct proc_ns_operations {
1818
const char *name;
1919
const char *real_ns_name;
20-
int type;
2120
struct ns_common *(*get)(struct task_struct *task);
2221
void (*put)(struct ns_common *ns);
2322
int (*install)(struct nsset *nsset, struct ns_common *ns);

init/version-timestamp.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <linux/utsname.h>
99

1010
struct uts_namespace init_uts_ns = {
11+
.ns.ns_type = ns_common_type(&init_uts_ns),
1112
.ns.__ns_ref = REFCOUNT_INIT(2),
1213
.name = {
1314
.sysname = UTS_SYSNAME,

ipc/msgutil.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ struct ipc_namespace init_ipc_ns = {
3333
#ifdef CONFIG_IPC_NS
3434
.ns.ops = &ipcns_operations,
3535
#endif
36+
.ns.ns_type = ns_common_type(&init_ipc_ns),
3637
};
3738

3839
struct msg_msgseg {

ipc/namespace.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,6 @@ static struct user_namespace *ipcns_owner(struct ns_common *ns)
248248

249249
const struct proc_ns_operations ipcns_operations = {
250250
.name = "ipc",
251-
.type = CLONE_NEWIPC,
252251
.get = ipcns_get,
253252
.put = ipcns_put,
254253
.install = ipcns_install,

kernel/cgroup/cgroup.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ struct cgroup_namespace init_cgroup_ns = {
224224
.ns.ops = &cgroupns_operations,
225225
.ns.inum = ns_init_inum(&init_cgroup_ns),
226226
.root_cset = &init_css_set,
227+
.ns.ns_type = ns_common_type(&init_cgroup_ns),
227228
};
228229

229230
static struct file_system_type cgroup2_fs_type;

kernel/cgroup/namespace.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,6 @@ static struct user_namespace *cgroupns_owner(struct ns_common *ns)
137137

138138
const struct proc_ns_operations cgroupns_operations = {
139139
.name = "cgroup",
140-
.type = CLONE_NEWCGROUP,
141140
.get = cgroupns_get,
142141
.put = cgroupns_put,
143142
.install = cgroupns_install,

0 commit comments

Comments
 (0)