namespaces-7.1-rc1.misc

Please consider pulling these changes from the signed namespaces-7.1-rc1.misc tag.
 
 Thanks!
 Christian
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQRAhzRXHqcMeLMyaSiRxhvAZXjcogUCadjZCwAKCRCRxhvAZXjc
 ols1AP9rA4gjJOTwHg0/pc+GL4qLSqUP3O4KeuJ8qccBcEUITAD/frpUjR11Ibw/
 F78/x1QhDPI8PCcw7kEyAPTfDb9VsgU=
 =5HBm
 -----END PGP SIGNATURE-----

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
This commit is contained in:
Linus Torvalds 2026-04-13 13:02:49 -07:00
commit dc0dfa7338
3 changed files with 41 additions and 23 deletions

View File

@ -7,6 +7,7 @@
#include <linux/rbtree.h>
#include <linux/refcount.h>
#include <linux/types.h>
#include <uapi/linux/sched.h>
struct cgroup_namespace;
struct dentry;
@ -184,15 +185,38 @@ struct ns_common {
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_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)
/*
* FOR_EACH_NS_TYPE - Canonical list of namespace types
*
* Enumerates all (struct type, CLONE_NEW* flag) pairs. This is the
* single source of truth used to derive ns_common_type() and
* CLONE_NS_ALL. When adding a new namespace type, add a single entry
* here; all consumers update automatically.
*
* @X: Callback macro taking (struct_name, clone_flag) as arguments.
*/
#define FOR_EACH_NS_TYPE(X) \
X(cgroup_namespace, CLONE_NEWCGROUP) \
X(ipc_namespace, CLONE_NEWIPC) \
X(mnt_namespace, CLONE_NEWNS) \
X(net, CLONE_NEWNET) \
X(pid_namespace, CLONE_NEWPID) \
X(time_namespace, CLONE_NEWTIME) \
X(user_namespace, CLONE_NEWUSER) \
X(uts_namespace, CLONE_NEWUTS)
/* Bitmask of all known CLONE_NEW* flags. */
#define _NS_TYPE_FLAG_OR(struct_name, flag) | (flag)
#define CLONE_NS_ALL (0 FOR_EACH_NS_TYPE(_NS_TYPE_FLAG_OR))
/*
* ns_common_type - Map a namespace struct pointer to its CLONE_NEW* flag
*
* Uses a leading-comma pattern so the FOR_EACH_NS_TYPE expansion
* produces ", struct foo *: FLAG" entries without a trailing comma.
*/
#define _NS_TYPE_ASSOC(struct_name, flag) , struct struct_name *: (flag)
#define ns_common_type(__ns) _Generic((__ns)FOR_EACH_NS_TYPE(_NS_TYPE_ASSOC))
#endif /* _LINUX_NS_COMMON_TYPES_H */

View File

@ -46,6 +46,7 @@
#include <linux/mm_inline.h>
#include <linux/memblock.h>
#include <linux/nsproxy.h>
#include <linux/ns/ns_common_types.h>
#include <linux/capability.h>
#include <linux/cpu.h>
#include <linux/cgroup.h>
@ -3045,11 +3046,9 @@ void __init proc_caches_init(void)
*/
static int check_unshare_flags(unsigned long unshare_flags)
{
if (unshare_flags & ~(CLONE_THREAD|CLONE_FS|CLONE_NEWNS|CLONE_SIGHAND|
if (unshare_flags & ~(CLONE_THREAD|CLONE_FS|CLONE_SIGHAND|
CLONE_VM|CLONE_FILES|CLONE_SYSVSEM|
CLONE_NEWUTS|CLONE_NEWIPC|CLONE_NEWNET|
CLONE_NEWUSER|CLONE_NEWPID|CLONE_NEWCGROUP|
CLONE_NEWTIME))
CLONE_NS_ALL))
return -EINVAL;
/*
* Not implemented, but pretend it works if there is nothing

View File

@ -12,6 +12,7 @@
#include <linux/slab.h>
#include <linux/export.h>
#include <linux/nsproxy.h>
#include <linux/ns/ns_common_types.h>
#include <linux/init_task.h>
#include <linux/mnt_namespace.h>
#include <linux/utsname.h>
@ -170,9 +171,7 @@ int copy_namespaces(u64 flags, struct task_struct *tsk)
struct user_namespace *user_ns = task_cred_xxx(tsk, user_ns);
struct nsproxy *new_ns;
if (likely(!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC |
CLONE_NEWPID | CLONE_NEWNET |
CLONE_NEWCGROUP | CLONE_NEWTIME)))) {
if (likely(!(flags & (CLONE_NS_ALL & ~CLONE_NEWUSER)))) {
if ((flags & CLONE_VM) ||
likely(old_ns->time_ns_for_children == old_ns->time_ns)) {
get_nsproxy(old_ns);
@ -214,9 +213,7 @@ int unshare_nsproxy_namespaces(unsigned long unshare_flags,
struct user_namespace *user_ns;
int err = 0;
if (!(unshare_flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC |
CLONE_NEWNET | CLONE_NEWPID | CLONE_NEWCGROUP |
CLONE_NEWTIME)))
if (!(unshare_flags & (CLONE_NS_ALL & ~CLONE_NEWUSER)))
return 0;
user_ns = new_cred ? new_cred->user_ns : current_user_ns();
@ -292,9 +289,7 @@ int exec_task_namespaces(void)
static int check_setns_flags(unsigned long flags)
{
if (!flags || (flags & ~(CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC |
CLONE_NEWNET | CLONE_NEWTIME | CLONE_NEWUSER |
CLONE_NEWPID | CLONE_NEWCGROUP)))
if (!flags || (flags & ~CLONE_NS_ALL))
return -EINVAL;
#ifndef CONFIG_USER_NS