Skip to content

Commit dc0dfa7

Browse files
committed
Merge tag 'namespaces-7.1-rc1.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
Pull namespace update from Christian Brauner: "Add two simple helper macros for the namespace infrastructure" * tag 'namespaces-7.1-rc1.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: nsproxy: Add FOR_EACH_NS_TYPE() X-macro and CLONE_NS_ALL
2 parents fc825e5 + 935a049 commit dc0dfa7

3 files changed

Lines changed: 41 additions & 23 deletions

File tree

include/linux/ns/ns_common_types.h

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <linux/rbtree.h>
88
#include <linux/refcount.h>
99
#include <linux/types.h>
10+
#include <uapi/linux/sched.h>
1011

1112
struct cgroup_namespace;
1213
struct dentry;
@@ -184,15 +185,38 @@ struct ns_common {
184185
struct user_namespace *: (IS_ENABLED(CONFIG_USER_NS) ? &userns_operations : NULL), \
185186
struct uts_namespace *: (IS_ENABLED(CONFIG_UTS_NS) ? &utsns_operations : NULL))
186187

187-
#define ns_common_type(__ns) \
188-
_Generic((__ns), \
189-
struct cgroup_namespace *: CLONE_NEWCGROUP, \
190-
struct ipc_namespace *: CLONE_NEWIPC, \
191-
struct mnt_namespace *: CLONE_NEWNS, \
192-
struct net *: CLONE_NEWNET, \
193-
struct pid_namespace *: CLONE_NEWPID, \
194-
struct time_namespace *: CLONE_NEWTIME, \
195-
struct user_namespace *: CLONE_NEWUSER, \
196-
struct uts_namespace *: CLONE_NEWUTS)
188+
/*
189+
* FOR_EACH_NS_TYPE - Canonical list of namespace types
190+
*
191+
* Enumerates all (struct type, CLONE_NEW* flag) pairs. This is the
192+
* single source of truth used to derive ns_common_type() and
193+
* CLONE_NS_ALL. When adding a new namespace type, add a single entry
194+
* here; all consumers update automatically.
195+
*
196+
* @X: Callback macro taking (struct_name, clone_flag) as arguments.
197+
*/
198+
#define FOR_EACH_NS_TYPE(X) \
199+
X(cgroup_namespace, CLONE_NEWCGROUP) \
200+
X(ipc_namespace, CLONE_NEWIPC) \
201+
X(mnt_namespace, CLONE_NEWNS) \
202+
X(net, CLONE_NEWNET) \
203+
X(pid_namespace, CLONE_NEWPID) \
204+
X(time_namespace, CLONE_NEWTIME) \
205+
X(user_namespace, CLONE_NEWUSER) \
206+
X(uts_namespace, CLONE_NEWUTS)
207+
208+
/* Bitmask of all known CLONE_NEW* flags. */
209+
#define _NS_TYPE_FLAG_OR(struct_name, flag) | (flag)
210+
#define CLONE_NS_ALL (0 FOR_EACH_NS_TYPE(_NS_TYPE_FLAG_OR))
211+
212+
/*
213+
* ns_common_type - Map a namespace struct pointer to its CLONE_NEW* flag
214+
*
215+
* Uses a leading-comma pattern so the FOR_EACH_NS_TYPE expansion
216+
* produces ", struct foo *: FLAG" entries without a trailing comma.
217+
*/
218+
#define _NS_TYPE_ASSOC(struct_name, flag) , struct struct_name *: (flag)
219+
220+
#define ns_common_type(__ns) _Generic((__ns)FOR_EACH_NS_TYPE(_NS_TYPE_ASSOC))
197221

198222
#endif /* _LINUX_NS_COMMON_TYPES_H */

kernel/fork.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
#include <linux/mm_inline.h>
4747
#include <linux/memblock.h>
4848
#include <linux/nsproxy.h>
49+
#include <linux/ns/ns_common_types.h>
4950
#include <linux/capability.h>
5051
#include <linux/cpu.h>
5152
#include <linux/cgroup.h>
@@ -3045,11 +3046,9 @@ void __init proc_caches_init(void)
30453046
*/
30463047
static int check_unshare_flags(unsigned long unshare_flags)
30473048
{
3048-
if (unshare_flags & ~(CLONE_THREAD|CLONE_FS|CLONE_NEWNS|CLONE_SIGHAND|
3049+
if (unshare_flags & ~(CLONE_THREAD|CLONE_FS|CLONE_SIGHAND|
30493050
CLONE_VM|CLONE_FILES|CLONE_SYSVSEM|
3050-
CLONE_NEWUTS|CLONE_NEWIPC|CLONE_NEWNET|
3051-
CLONE_NEWUSER|CLONE_NEWPID|CLONE_NEWCGROUP|
3052-
CLONE_NEWTIME))
3051+
CLONE_NS_ALL))
30533052
return -EINVAL;
30543053
/*
30553054
* Not implemented, but pretend it works if there is nothing

kernel/nsproxy.c

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <linux/slab.h>
1313
#include <linux/export.h>
1414
#include <linux/nsproxy.h>
15+
#include <linux/ns/ns_common_types.h>
1516
#include <linux/init_task.h>
1617
#include <linux/mnt_namespace.h>
1718
#include <linux/utsname.h>
@@ -170,9 +171,7 @@ int copy_namespaces(u64 flags, struct task_struct *tsk)
170171
struct user_namespace *user_ns = task_cred_xxx(tsk, user_ns);
171172
struct nsproxy *new_ns;
172173

173-
if (likely(!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC |
174-
CLONE_NEWPID | CLONE_NEWNET |
175-
CLONE_NEWCGROUP | CLONE_NEWTIME)))) {
174+
if (likely(!(flags & (CLONE_NS_ALL & ~CLONE_NEWUSER)))) {
176175
if ((flags & CLONE_VM) ||
177176
likely(old_ns->time_ns_for_children == old_ns->time_ns)) {
178177
get_nsproxy(old_ns);
@@ -214,9 +213,7 @@ int unshare_nsproxy_namespaces(unsigned long unshare_flags,
214213
struct user_namespace *user_ns;
215214
int err = 0;
216215

217-
if (!(unshare_flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC |
218-
CLONE_NEWNET | CLONE_NEWPID | CLONE_NEWCGROUP |
219-
CLONE_NEWTIME)))
216+
if (!(unshare_flags & (CLONE_NS_ALL & ~CLONE_NEWUSER)))
220217
return 0;
221218

222219
user_ns = new_cred ? new_cred->user_ns : current_user_ns();
@@ -292,9 +289,7 @@ int exec_task_namespaces(void)
292289

293290
static int check_setns_flags(unsigned long flags)
294291
{
295-
if (!flags || (flags & ~(CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC |
296-
CLONE_NEWNET | CLONE_NEWTIME | CLONE_NEWUSER |
297-
CLONE_NEWPID | CLONE_NEWCGROUP)))
292+
if (!flags || (flags & ~CLONE_NS_ALL))
298293
return -EINVAL;
299294

300295
#ifndef CONFIG_USER_NS

0 commit comments

Comments
 (0)