public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH RFC] security: add LSM blob and hooks for namespaces
@ 2026-02-16 13:52 Christian Brauner
  2026-02-16 17:34 ` Casey Schaufler
  2026-02-16 18:53 ` Paul Moore
  0 siblings, 2 replies; 10+ messages in thread
From: Christian Brauner @ 2026-02-16 13:52 UTC (permalink / raw)
  To: Paul Moore
  Cc: James Morris, linux-security-module, linux-kernel,
	Christian Brauner

All namespace types now share the same ns_common infrastructure. Extend
this to include a security blob so LSMs can start managing namespaces
uniformly without having to add one-off hooks or security fields to
every individual namespace type.

Add a ns_security pointer to ns_common and the corresponding lbs_ns
blob size to lsm_blob_sizes. Allocation and freeing hooks are called
from the common __ns_common_init() and __ns_common_free() paths so
every namespace type gets covered in one go. All information about the
namespace type and the appropriate casting helpers to get at the
containing namespace are available via ns_common making it
straightforward for LSMs to differentiate when they need to.

A namespace_install hook is called from validate_ns() during setns(2)
giving LSMs a chance to enforce policy on namespace transitions.

Individual namespace types can still have their own specialized security
hooks when needed. This is just the common baseline that makes it easy
to track and manage namespaces from the security side without requiring
every namespace type to reinvent the wheel.

Signed-off-by: Christian Brauner <brauner@kernel.org>
---
 include/linux/lsm_hook_defs.h      |  3 ++
 include/linux/lsm_hooks.h          |  1 +
 include/linux/ns/ns_common_types.h |  3 ++
 include/linux/security.h           | 20 ++++++++++
 kernel/nscommon.c                  | 12 ++++++
 kernel/nsproxy.c                   |  8 +++-
 security/lsm_init.c                |  2 +
 security/security.c                | 76 ++++++++++++++++++++++++++++++++++++++
 8 files changed, 124 insertions(+), 1 deletion(-)

diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
index 8c42b4bde09c..fefd3aa6d8f4 100644
--- a/include/linux/lsm_hook_defs.h
+++ b/include/linux/lsm_hook_defs.h
@@ -260,6 +260,9 @@ LSM_HOOK(int, -ENOSYS, task_prctl, int option, unsigned long arg2,
 LSM_HOOK(void, LSM_RET_VOID, task_to_inode, struct task_struct *p,
 	 struct inode *inode)
 LSM_HOOK(int, 0, userns_create, const struct cred *cred)
+LSM_HOOK(int, 0, namespace_alloc, struct ns_common *ns)
+LSM_HOOK(void, LSM_RET_VOID, namespace_free, struct ns_common *ns)
+LSM_HOOK(int, 0, namespace_install, const struct nsset *nsset, struct ns_common *ns)
 LSM_HOOK(int, 0, ipc_permission, struct kern_ipc_perm *ipcp, short flag)
 LSM_HOOK(void, LSM_RET_VOID, ipc_getlsmprop, struct kern_ipc_perm *ipcp,
 	 struct lsm_prop *prop)
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index d48bf0ad26f4..3e7afe76e86c 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -111,6 +111,7 @@ struct lsm_blob_sizes {
 	unsigned int lbs_ipc;
 	unsigned int lbs_key;
 	unsigned int lbs_msg_msg;
+	unsigned int lbs_ns;
 	unsigned int lbs_perf_event;
 	unsigned int lbs_task;
 	unsigned int lbs_xattr_count; /* num xattr slots in new_xattrs array */
diff --git a/include/linux/ns/ns_common_types.h b/include/linux/ns/ns_common_types.h
index 0014fbc1c626..170288e2e895 100644
--- a/include/linux/ns/ns_common_types.h
+++ b/include/linux/ns/ns_common_types.h
@@ -115,6 +115,9 @@ struct ns_common {
 	struct dentry *stashed;
 	const struct proc_ns_operations *ops;
 	unsigned int inum;
+#ifdef CONFIG_SECURITY
+	void *ns_security;
+#endif
 	union {
 		struct ns_tree;
 		struct rcu_head ns_rcu;
diff --git a/include/linux/security.h b/include/linux/security.h
index 83a646d72f6f..611b9098367d 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -67,6 +67,7 @@ enum fs_value_type;
 struct watch;
 struct watch_notification;
 struct lsm_ctx;
+struct nsset;
 
 /* Default (no) options for the capable function */
 #define CAP_OPT_NONE 0x0
@@ -80,6 +81,7 @@ struct lsm_ctx;
 
 struct ctl_table;
 struct audit_krule;
+struct ns_common;
 struct user_namespace;
 struct timezone;
 
@@ -533,6 +535,9 @@ int security_task_prctl(int option, unsigned long arg2, unsigned long arg3,
 			unsigned long arg4, unsigned long arg5);
 void security_task_to_inode(struct task_struct *p, struct inode *inode);
 int security_create_user_ns(const struct cred *cred);
+int security_namespace_alloc(struct ns_common *ns);
+void security_namespace_free(struct ns_common *ns);
+int security_namespace_install(const struct nsset *nsset, struct ns_common *ns);
 int security_ipc_permission(struct kern_ipc_perm *ipcp, short flag);
 void security_ipc_getlsmprop(struct kern_ipc_perm *ipcp, struct lsm_prop *prop);
 int security_msg_msg_alloc(struct msg_msg *msg);
@@ -1407,6 +1412,21 @@ static inline int security_create_user_ns(const struct cred *cred)
 	return 0;
 }
 
+static inline int security_namespace_alloc(struct ns_common *ns)
+{
+	return 0;
+}
+
+static inline void security_namespace_free(struct ns_common *ns)
+{
+}
+
+static inline int security_namespace_install(const struct nsset *nsset,
+					     struct ns_common *ns)
+{
+	return 0;
+}
+
 static inline int security_ipc_permission(struct kern_ipc_perm *ipcp,
 					  short flag)
 {
diff --git a/kernel/nscommon.c b/kernel/nscommon.c
index bdc3c86231d3..de774e374f9d 100644
--- a/kernel/nscommon.c
+++ b/kernel/nscommon.c
@@ -4,6 +4,7 @@
 #include <linux/ns_common.h>
 #include <linux/nstree.h>
 #include <linux/proc_ns.h>
+#include <linux/security.h>
 #include <linux/user_namespace.h>
 #include <linux/vfsdebug.h>
 
@@ -59,6 +60,9 @@ int __ns_common_init(struct ns_common *ns, u32 ns_type, const struct proc_ns_ope
 
 	refcount_set(&ns->__ns_ref, 1);
 	ns->stashed = NULL;
+#ifdef CONFIG_SECURITY
+	ns->ns_security = NULL;
+#endif
 	ns->ops = ops;
 	ns->ns_id = 0;
 	ns->ns_type = ns_type;
@@ -77,6 +81,13 @@ int __ns_common_init(struct ns_common *ns, u32 ns_type, const struct proc_ns_ope
 		ret = proc_alloc_inum(&ns->inum);
 	if (ret)
 		return ret;
+
+	ret = security_namespace_alloc(ns);
+	if (ret) {
+		proc_free_inum(ns->inum);
+		return ret;
+	}
+
 	/*
 	 * Tree ref starts at 0. It's incremented when namespace enters
 	 * active use (installed in nsproxy) and decremented when all
@@ -91,6 +102,7 @@ int __ns_common_init(struct ns_common *ns, u32 ns_type, const struct proc_ns_ope
 
 void __ns_common_free(struct ns_common *ns)
 {
+	security_namespace_free(ns);
 	proc_free_inum(ns->inum);
 }
 
diff --git a/kernel/nsproxy.c b/kernel/nsproxy.c
index 259c4b4f1eeb..f0b30d1907e7 100644
--- a/kernel/nsproxy.c
+++ b/kernel/nsproxy.c
@@ -379,7 +379,13 @@ static int prepare_nsset(unsigned flags, struct nsset *nsset)
 
 static inline int validate_ns(struct nsset *nsset, struct ns_common *ns)
 {
-	return ns->ops->install(nsset, ns);
+	int ret;
+
+	ret = ns->ops->install(nsset, ns);
+	if (ret)
+		return ret;
+
+	return security_namespace_install(nsset, ns);
 }
 
 /*
diff --git a/security/lsm_init.c b/security/lsm_init.c
index 573e2a7250c4..637c2d65e131 100644
--- a/security/lsm_init.c
+++ b/security/lsm_init.c
@@ -301,6 +301,7 @@ static void __init lsm_prepare(struct lsm_info *lsm)
 	lsm_blob_size_update(&blobs->lbs_ipc, &blob_sizes.lbs_ipc);
 	lsm_blob_size_update(&blobs->lbs_key, &blob_sizes.lbs_key);
 	lsm_blob_size_update(&blobs->lbs_msg_msg, &blob_sizes.lbs_msg_msg);
+	lsm_blob_size_update(&blobs->lbs_ns, &blob_sizes.lbs_ns);
 	lsm_blob_size_update(&blobs->lbs_perf_event,
 			     &blob_sizes.lbs_perf_event);
 	lsm_blob_size_update(&blobs->lbs_sock, &blob_sizes.lbs_sock);
@@ -446,6 +447,7 @@ int __init security_init(void)
 		lsm_pr("blob(ipc) size %d\n", blob_sizes.lbs_ipc);
 		lsm_pr("blob(key) size %d\n", blob_sizes.lbs_key);
 		lsm_pr("blob(msg_msg)_size %d\n", blob_sizes.lbs_msg_msg);
+		lsm_pr("blob(ns) size %d\n", blob_sizes.lbs_ns);
 		lsm_pr("blob(sock) size %d\n", blob_sizes.lbs_sock);
 		lsm_pr("blob(superblock) size %d\n", blob_sizes.lbs_superblock);
 		lsm_pr("blob(perf_event) size %d\n", blob_sizes.lbs_perf_event);
diff --git a/security/security.c b/security/security.c
index 67af9228c4e9..dcf073cac848 100644
--- a/security/security.c
+++ b/security/security.c
@@ -26,6 +26,7 @@
 #include <linux/string.h>
 #include <linux/xattr.h>
 #include <linux/msg.h>
+#include <linux/ns_common.h>
 #include <linux/overflow.h>
 #include <linux/perf_event.h>
 #include <linux/fs.h>
@@ -355,6 +356,19 @@ static int lsm_superblock_alloc(struct super_block *sb)
 			      GFP_KERNEL);
 }
 
+/**
+ * lsm_ns_alloc - allocate a composite namespace blob
+ * @ns: the namespace that needs a blob
+ *
+ * Allocate the namespace blob for all the modules
+ *
+ * Returns 0, or -ENOMEM if memory can't be allocated.
+ */
+static int lsm_ns_alloc(struct ns_common *ns)
+{
+	return lsm_blob_alloc(&ns->ns_security, blob_sizes.lbs_ns, GFP_KERNEL);
+}
+
 /**
  * lsm_fill_user_ctx - Fill a user space lsm_ctx structure
  * @uctx: a userspace LSM context to be filled
@@ -3255,6 +3269,68 @@ int security_create_user_ns(const struct cred *cred)
 	return call_int_hook(userns_create, cred);
 }
 
+/**
+ * security_namespace_alloc() - Allocate LSM security data for a namespace
+ * @ns: the namespace being allocated
+ *
+ * Allocate and attach security data to the namespace. The namespace type
+ * is available via ns->ns_type, and the owning user namespace (if any)
+ * via ns->ops->owner(ns).
+ *
+ * Return: Returns 0 if successful, otherwise < 0 error code.
+ */
+int security_namespace_alloc(struct ns_common *ns)
+{
+	int rc;
+
+	rc = lsm_ns_alloc(ns);
+	if (unlikely(rc))
+		return rc;
+
+	rc = call_int_hook(namespace_alloc, ns);
+	if (unlikely(rc))
+		security_namespace_free(ns);
+
+	return rc;
+}
+
+/**
+ * security_namespace_free() - Release LSM security data from a namespace
+ * @ns: the namespace being freed
+ *
+ * Release security data attached to the namespace. Called before the
+ * namespace structure is freed.
+ *
+ * Note: The namespace may be freed via kfree_rcu(). LSMs must use
+ * RCU-safe freeing for any data that might be accessed by concurrent
+ * RCU readers.
+ */
+void security_namespace_free(struct ns_common *ns)
+{
+	if (!ns->ns_security)
+		return;
+
+	call_void_hook(namespace_free, ns);
+
+	kfree(ns->ns_security);
+	ns->ns_security = NULL;
+}
+
+/**
+ * security_namespace_install() - Check permission to install a namespace
+ * @nsset: the target nsset being configured
+ * @ns: the namespace being installed
+ *
+ * Check permission before allowing a namespace to be installed into the
+ * process's set of namespaces via setns(2).
+ *
+ * Return: Returns 0 if permission is granted, otherwise < 0 error code.
+ */
+int security_namespace_install(const struct nsset *nsset, struct ns_common *ns)
+{
+	return call_int_hook(namespace_install, nsset, ns);
+}
+
 /**
  * security_ipc_permission() - Check if sysv ipc access is allowed
  * @ipcp: ipc permission structure

---
base-commit: 72c395024dac5e215136cbff793455f065603b06
change-id: 20260206-work-security-namespace-d6a736082bcf


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH RFC] security: add LSM blob and hooks for namespaces
  2026-02-16 13:52 [PATCH RFC] security: add LSM blob and hooks for namespaces Christian Brauner
@ 2026-02-16 17:34 ` Casey Schaufler
  2026-02-17  9:38   ` Christian Brauner
  2026-02-16 18:53 ` Paul Moore
  1 sibling, 1 reply; 10+ messages in thread
From: Casey Schaufler @ 2026-02-16 17:34 UTC (permalink / raw)
  To: Christian Brauner, Paul Moore
  Cc: James Morris, linux-security-module, linux-kernel,
	Casey Schaufler

On 2/16/2026 5:52 AM, Christian Brauner wrote:
> All namespace types now share the same ns_common infrastructure. Extend
> this to include a security blob so LSMs can start managing namespaces
> uniformly without having to add one-off hooks or security fields to
> every individual namespace type.

The implementation appears sound.

I have to question whether having LSM controls on namespaces is reasonable.
I suppose that you could have a system where (for example) SELinux runs
in permissive mode except within a specific user namespace, where it would
enforce policy. Do you have a use case in mind? 

>
> Add a ns_security pointer to ns_common and the corresponding lbs_ns
> blob size to lsm_blob_sizes. Allocation and freeing hooks are called
> from the common __ns_common_init() and __ns_common_free() paths so
> every namespace type gets covered in one go. All information about the
> namespace type and the appropriate casting helpers to get at the
> containing namespace are available via ns_common making it
> straightforward for LSMs to differentiate when they need to.
>
> A namespace_install hook is called from validate_ns() during setns(2)
> giving LSMs a chance to enforce policy on namespace transitions.
>
> Individual namespace types can still have their own specialized security
> hooks when needed. This is just the common baseline that makes it easy
> to track and manage namespaces from the security side without requiring
> every namespace type to reinvent the wheel.
>
> Signed-off-by: Christian Brauner <brauner@kernel.org>
> ---
>  include/linux/lsm_hook_defs.h      |  3 ++
>  include/linux/lsm_hooks.h          |  1 +
>  include/linux/ns/ns_common_types.h |  3 ++
>  include/linux/security.h           | 20 ++++++++++
>  kernel/nscommon.c                  | 12 ++++++
>  kernel/nsproxy.c                   |  8 +++-
>  security/lsm_init.c                |  2 +
>  security/security.c                | 76 ++++++++++++++++++++++++++++++++++++++
>  8 files changed, 124 insertions(+), 1 deletion(-)
>
> diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
> index 8c42b4bde09c..fefd3aa6d8f4 100644
> --- a/include/linux/lsm_hook_defs.h
> +++ b/include/linux/lsm_hook_defs.h
> @@ -260,6 +260,9 @@ LSM_HOOK(int, -ENOSYS, task_prctl, int option, unsigned long arg2,
>  LSM_HOOK(void, LSM_RET_VOID, task_to_inode, struct task_struct *p,
>  	 struct inode *inode)
>  LSM_HOOK(int, 0, userns_create, const struct cred *cred)
> +LSM_HOOK(int, 0, namespace_alloc, struct ns_common *ns)
> +LSM_HOOK(void, LSM_RET_VOID, namespace_free, struct ns_common *ns)
> +LSM_HOOK(int, 0, namespace_install, const struct nsset *nsset, struct ns_common *ns)
>  LSM_HOOK(int, 0, ipc_permission, struct kern_ipc_perm *ipcp, short flag)
>  LSM_HOOK(void, LSM_RET_VOID, ipc_getlsmprop, struct kern_ipc_perm *ipcp,
>  	 struct lsm_prop *prop)
> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
> index d48bf0ad26f4..3e7afe76e86c 100644
> --- a/include/linux/lsm_hooks.h
> +++ b/include/linux/lsm_hooks.h
> @@ -111,6 +111,7 @@ struct lsm_blob_sizes {
>  	unsigned int lbs_ipc;
>  	unsigned int lbs_key;
>  	unsigned int lbs_msg_msg;
> +	unsigned int lbs_ns;
>  	unsigned int lbs_perf_event;
>  	unsigned int lbs_task;
>  	unsigned int lbs_xattr_count; /* num xattr slots in new_xattrs array */
> diff --git a/include/linux/ns/ns_common_types.h b/include/linux/ns/ns_common_types.h
> index 0014fbc1c626..170288e2e895 100644
> --- a/include/linux/ns/ns_common_types.h
> +++ b/include/linux/ns/ns_common_types.h
> @@ -115,6 +115,9 @@ struct ns_common {
>  	struct dentry *stashed;
>  	const struct proc_ns_operations *ops;
>  	unsigned int inum;
> +#ifdef CONFIG_SECURITY
> +	void *ns_security;
> +#endif
>  	union {
>  		struct ns_tree;
>  		struct rcu_head ns_rcu;
> diff --git a/include/linux/security.h b/include/linux/security.h
> index 83a646d72f6f..611b9098367d 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -67,6 +67,7 @@ enum fs_value_type;
>  struct watch;
>  struct watch_notification;
>  struct lsm_ctx;
> +struct nsset;
>  
>  /* Default (no) options for the capable function */
>  #define CAP_OPT_NONE 0x0
> @@ -80,6 +81,7 @@ struct lsm_ctx;
>  
>  struct ctl_table;
>  struct audit_krule;
> +struct ns_common;
>  struct user_namespace;
>  struct timezone;
>  
> @@ -533,6 +535,9 @@ int security_task_prctl(int option, unsigned long arg2, unsigned long arg3,
>  			unsigned long arg4, unsigned long arg5);
>  void security_task_to_inode(struct task_struct *p, struct inode *inode);
>  int security_create_user_ns(const struct cred *cred);
> +int security_namespace_alloc(struct ns_common *ns);
> +void security_namespace_free(struct ns_common *ns);
> +int security_namespace_install(const struct nsset *nsset, struct ns_common *ns);
>  int security_ipc_permission(struct kern_ipc_perm *ipcp, short flag);
>  void security_ipc_getlsmprop(struct kern_ipc_perm *ipcp, struct lsm_prop *prop);
>  int security_msg_msg_alloc(struct msg_msg *msg);
> @@ -1407,6 +1412,21 @@ static inline int security_create_user_ns(const struct cred *cred)
>  	return 0;
>  }
>  
> +static inline int security_namespace_alloc(struct ns_common *ns)
> +{
> +	return 0;
> +}
> +
> +static inline void security_namespace_free(struct ns_common *ns)
> +{
> +}
> +
> +static inline int security_namespace_install(const struct nsset *nsset,
> +					     struct ns_common *ns)
> +{
> +	return 0;
> +}
> +
>  static inline int security_ipc_permission(struct kern_ipc_perm *ipcp,
>  					  short flag)
>  {
> diff --git a/kernel/nscommon.c b/kernel/nscommon.c
> index bdc3c86231d3..de774e374f9d 100644
> --- a/kernel/nscommon.c
> +++ b/kernel/nscommon.c
> @@ -4,6 +4,7 @@
>  #include <linux/ns_common.h>
>  #include <linux/nstree.h>
>  #include <linux/proc_ns.h>
> +#include <linux/security.h>
>  #include <linux/user_namespace.h>
>  #include <linux/vfsdebug.h>
>  
> @@ -59,6 +60,9 @@ int __ns_common_init(struct ns_common *ns, u32 ns_type, const struct proc_ns_ope
>  
>  	refcount_set(&ns->__ns_ref, 1);
>  	ns->stashed = NULL;
> +#ifdef CONFIG_SECURITY
> +	ns->ns_security = NULL;
> +#endif
>  	ns->ops = ops;
>  	ns->ns_id = 0;
>  	ns->ns_type = ns_type;
> @@ -77,6 +81,13 @@ int __ns_common_init(struct ns_common *ns, u32 ns_type, const struct proc_ns_ope
>  		ret = proc_alloc_inum(&ns->inum);
>  	if (ret)
>  		return ret;
> +
> +	ret = security_namespace_alloc(ns);
> +	if (ret) {
> +		proc_free_inum(ns->inum);
> +		return ret;
> +	}
> +
>  	/*
>  	 * Tree ref starts at 0. It's incremented when namespace enters
>  	 * active use (installed in nsproxy) and decremented when all
> @@ -91,6 +102,7 @@ int __ns_common_init(struct ns_common *ns, u32 ns_type, const struct proc_ns_ope
>  
>  void __ns_common_free(struct ns_common *ns)
>  {
> +	security_namespace_free(ns);
>  	proc_free_inum(ns->inum);
>  }
>  
> diff --git a/kernel/nsproxy.c b/kernel/nsproxy.c
> index 259c4b4f1eeb..f0b30d1907e7 100644
> --- a/kernel/nsproxy.c
> +++ b/kernel/nsproxy.c
> @@ -379,7 +379,13 @@ static int prepare_nsset(unsigned flags, struct nsset *nsset)
>  
>  static inline int validate_ns(struct nsset *nsset, struct ns_common *ns)
>  {
> -	return ns->ops->install(nsset, ns);
> +	int ret;
> +
> +	ret = ns->ops->install(nsset, ns);
> +	if (ret)
> +		return ret;
> +
> +	return security_namespace_install(nsset, ns);
>  }
>  
>  /*
> diff --git a/security/lsm_init.c b/security/lsm_init.c
> index 573e2a7250c4..637c2d65e131 100644
> --- a/security/lsm_init.c
> +++ b/security/lsm_init.c
> @@ -301,6 +301,7 @@ static void __init lsm_prepare(struct lsm_info *lsm)
>  	lsm_blob_size_update(&blobs->lbs_ipc, &blob_sizes.lbs_ipc);
>  	lsm_blob_size_update(&blobs->lbs_key, &blob_sizes.lbs_key);
>  	lsm_blob_size_update(&blobs->lbs_msg_msg, &blob_sizes.lbs_msg_msg);
> +	lsm_blob_size_update(&blobs->lbs_ns, &blob_sizes.lbs_ns);
>  	lsm_blob_size_update(&blobs->lbs_perf_event,
>  			     &blob_sizes.lbs_perf_event);
>  	lsm_blob_size_update(&blobs->lbs_sock, &blob_sizes.lbs_sock);
> @@ -446,6 +447,7 @@ int __init security_init(void)
>  		lsm_pr("blob(ipc) size %d\n", blob_sizes.lbs_ipc);
>  		lsm_pr("blob(key) size %d\n", blob_sizes.lbs_key);
>  		lsm_pr("blob(msg_msg)_size %d\n", blob_sizes.lbs_msg_msg);
> +		lsm_pr("blob(ns) size %d\n", blob_sizes.lbs_ns);
>  		lsm_pr("blob(sock) size %d\n", blob_sizes.lbs_sock);
>  		lsm_pr("blob(superblock) size %d\n", blob_sizes.lbs_superblock);
>  		lsm_pr("blob(perf_event) size %d\n", blob_sizes.lbs_perf_event);
> diff --git a/security/security.c b/security/security.c
> index 67af9228c4e9..dcf073cac848 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -26,6 +26,7 @@
>  #include <linux/string.h>
>  #include <linux/xattr.h>
>  #include <linux/msg.h>
> +#include <linux/ns_common.h>
>  #include <linux/overflow.h>
>  #include <linux/perf_event.h>
>  #include <linux/fs.h>
> @@ -355,6 +356,19 @@ static int lsm_superblock_alloc(struct super_block *sb)
>  			      GFP_KERNEL);
>  }
>  
> +/**
> + * lsm_ns_alloc - allocate a composite namespace blob
> + * @ns: the namespace that needs a blob
> + *
> + * Allocate the namespace blob for all the modules
> + *
> + * Returns 0, or -ENOMEM if memory can't be allocated.
> + */
> +static int lsm_ns_alloc(struct ns_common *ns)
> +{
> +	return lsm_blob_alloc(&ns->ns_security, blob_sizes.lbs_ns, GFP_KERNEL);
> +}
> +
>  /**
>   * lsm_fill_user_ctx - Fill a user space lsm_ctx structure
>   * @uctx: a userspace LSM context to be filled
> @@ -3255,6 +3269,68 @@ int security_create_user_ns(const struct cred *cred)
>  	return call_int_hook(userns_create, cred);
>  }
>  
> +/**
> + * security_namespace_alloc() - Allocate LSM security data for a namespace
> + * @ns: the namespace being allocated
> + *
> + * Allocate and attach security data to the namespace. The namespace type
> + * is available via ns->ns_type, and the owning user namespace (if any)
> + * via ns->ops->owner(ns).
> + *
> + * Return: Returns 0 if successful, otherwise < 0 error code.
> + */
> +int security_namespace_alloc(struct ns_common *ns)
> +{
> +	int rc;
> +
> +	rc = lsm_ns_alloc(ns);
> +	if (unlikely(rc))
> +		return rc;
> +
> +	rc = call_int_hook(namespace_alloc, ns);
> +	if (unlikely(rc))
> +		security_namespace_free(ns);
> +
> +	return rc;
> +}
> +
> +/**
> + * security_namespace_free() - Release LSM security data from a namespace
> + * @ns: the namespace being freed
> + *
> + * Release security data attached to the namespace. Called before the
> + * namespace structure is freed.
> + *
> + * Note: The namespace may be freed via kfree_rcu(). LSMs must use
> + * RCU-safe freeing for any data that might be accessed by concurrent
> + * RCU readers.
> + */
> +void security_namespace_free(struct ns_common *ns)
> +{
> +	if (!ns->ns_security)
> +		return;
> +
> +	call_void_hook(namespace_free, ns);
> +
> +	kfree(ns->ns_security);
> +	ns->ns_security = NULL;
> +}
> +
> +/**
> + * security_namespace_install() - Check permission to install a namespace
> + * @nsset: the target nsset being configured
> + * @ns: the namespace being installed
> + *
> + * Check permission before allowing a namespace to be installed into the
> + * process's set of namespaces via setns(2).
> + *
> + * Return: Returns 0 if permission is granted, otherwise < 0 error code.
> + */
> +int security_namespace_install(const struct nsset *nsset, struct ns_common *ns)
> +{
> +	return call_int_hook(namespace_install, nsset, ns);
> +}
> +
>  /**
>   * security_ipc_permission() - Check if sysv ipc access is allowed
>   * @ipcp: ipc permission structure
>
> ---
> base-commit: 72c395024dac5e215136cbff793455f065603b06
> change-id: 20260206-work-security-namespace-d6a736082bcf
>
>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH RFC] security: add LSM blob and hooks for namespaces
  2026-02-16 13:52 [PATCH RFC] security: add LSM blob and hooks for namespaces Christian Brauner
  2026-02-16 17:34 ` Casey Schaufler
@ 2026-02-16 18:53 ` Paul Moore
  2026-02-17  8:54   ` Christian Brauner
  1 sibling, 1 reply; 10+ messages in thread
From: Paul Moore @ 2026-02-16 18:53 UTC (permalink / raw)
  To: Christian Brauner; +Cc: James Morris, linux-security-module, linux-kernel

On February 16, 2026 2:52:34 PM Christian Brauner <brauner@kernel.org> wrote:
> All namespace types now share the same ns_common infrastructure. Extend
> this to include a security blob so LSMs can start managing namespaces
> uniformly without having to add one-off hooks or security fields to
> every individual namespace type.
>
> Add a ns_security pointer to ns_common and the corresponding lbs_ns
> blob size to lsm_blob_sizes. Allocation and freeing hooks are called
> from the common __ns_common_init() and __ns_common_free() paths so
> every namespace type gets covered in one go. All information about the
> namespace type and the appropriate casting helpers to get at the
> containing namespace are available via ns_common making it
> straightforward for LSMs to differentiate when they need to.
>
> A namespace_install hook is called from validate_ns() during setns(2)
> giving LSMs a chance to enforce policy on namespace transitions.
>
> Individual namespace types can still have their own specialized security
> hooks when needed. This is just the common baseline that makes it easy
> to track and manage namespaces from the security side without requiring
> every namespace type to reinvent the wheel.
>
> Signed-off-by: Christian Brauner <brauner@kernel.org>
> ---
> include/linux/lsm_hook_defs.h      |  3 ++
> include/linux/lsm_hooks.h          |  1 +
> include/linux/ns/ns_common_types.h |  3 ++
> include/linux/security.h           | 20 ++++++++++
> kernel/nscommon.c                  | 12 ++++++
> kernel/nsproxy.c                   |  8 +++-
> security/lsm_init.c                |  2 +
> security/security.c                | 76 ++++++++++++++++++++++++++++++++++++++
> 8 files changed, 124 insertions(+), 1 deletion(-)

I still have limited network access for a few more days, but a couple of 
quick comments in no particular order ...

Generally speaking we don't add things to the LSM interface without a user, 
and I can't think of a good reason why we would want to do things 
differently here.  This means that when you propose something like this you 
should also propose an addition to one of the in-tree LSMs to make use of 
it. While the guidance doc linked below (also linked in the LSM MAINTAINERS 
entry) doesn't have any guidance for the LSM blobs as they are generally a 
byproduct of the hooks, if you are looking for some general info I think 
the bits on adding a new LSM hook would be very close to what we would 
expect for blob additions.

https://github.com/LinuxSecurityModule/kernel/blob/main/README.md

Getting to the specifics of namespace related APIs, we've had a lot of 
discussions about namespacing and my current opinion is that we need to 
sort out if we want a userspace API at the LSM framework layer, or if we 
want to do that at the individual LSM layer; there is a lot of nuance there 
and while one option may seem like an obvious choice, we need some more 
discussion and I need a chance to get caught up on the threads. Once we 
have an API decision then we can start sorting out the implementation 
details like the LSM blobs.

--
paul-moore.com
>




^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH RFC] security: add LSM blob and hooks for namespaces
  2026-02-16 18:53 ` Paul Moore
@ 2026-02-17  8:54   ` Christian Brauner
  2026-02-17 11:33     ` Paul Moore
  0 siblings, 1 reply; 10+ messages in thread
From: Christian Brauner @ 2026-02-17  8:54 UTC (permalink / raw)
  To: Paul Moore; +Cc: James Morris, linux-security-module, linux-kernel

On Mon, Feb 16, 2026 at 07:53:11PM +0100, Paul Moore wrote:
> On February 16, 2026 2:52:34 PM Christian Brauner <brauner@kernel.org> wrote:
> > All namespace types now share the same ns_common infrastructure. Extend
> > this to include a security blob so LSMs can start managing namespaces
> > uniformly without having to add one-off hooks or security fields to
> > every individual namespace type.
> > 
> > Add a ns_security pointer to ns_common and the corresponding lbs_ns
> > blob size to lsm_blob_sizes. Allocation and freeing hooks are called
> > from the common __ns_common_init() and __ns_common_free() paths so
> > every namespace type gets covered in one go. All information about the
> > namespace type and the appropriate casting helpers to get at the
> > containing namespace are available via ns_common making it
> > straightforward for LSMs to differentiate when they need to.
> > 
> > A namespace_install hook is called from validate_ns() during setns(2)
> > giving LSMs a chance to enforce policy on namespace transitions.
> > 
> > Individual namespace types can still have their own specialized security
> > hooks when needed. This is just the common baseline that makes it easy
> > to track and manage namespaces from the security side without requiring
> > every namespace type to reinvent the wheel.
> > 
> > Signed-off-by: Christian Brauner <brauner@kernel.org>
> > ---
> > include/linux/lsm_hook_defs.h      |  3 ++
> > include/linux/lsm_hooks.h          |  1 +
> > include/linux/ns/ns_common_types.h |  3 ++
> > include/linux/security.h           | 20 ++++++++++
> > kernel/nscommon.c                  | 12 ++++++
> > kernel/nsproxy.c                   |  8 +++-
> > security/lsm_init.c                |  2 +
> > security/security.c                | 76 ++++++++++++++++++++++++++++++++++++++
> > 8 files changed, 124 insertions(+), 1 deletion(-)
> 
> I still have limited network access for a few more days, but a couple of
> quick comments in no particular order ...
> 
> Generally speaking we don't add things to the LSM interface without a user,
> and I can't think of a good reason why we would want to do things
> differently here.  This means that when you propose something like this you
> should also propose an addition to one of the in-tree LSMs to make use of
> it. While the guidance doc linked below (also linked in the LSM MAINTAINERS
> entry) doesn't have any guidance for the LSM blobs as they are generally a
> byproduct of the hooks, if you are looking for some general info I think the
> bits on adding a new LSM hook would be very close to what we would expect
> for blob additions.
> 
> https://github.com/LinuxSecurityModule/kernel/blob/main/README.md
> 
> Getting to the specifics of namespace related APIs, we've had a lot of
> discussions about namespacing and my current opinion is that we need to sort
> out if we want a userspace API at the LSM framework layer, or if we want to
> do that at the individual LSM layer; there is a lot of nuance there and
> while one option may seem like an obvious choice, we need some more
> discussion and I need a chance to get caught up on the threads. Once we have
> an API decision then we can start sorting out the implementation details
> like the LSM blobs.

I might be misunderstanding you but what you are talking about seems
namespacing the LSM layer itself.

But I cannot stress enough this is not at all what this patchset is
doing. :)

All that this patchset does is add new security hooks that get called
whenever a new pid, net, mount, ipc, ... namespace is created, freed, or
when someone wants to change into another namespace. We plan on using
this in systemd to supervise and track services.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH RFC] security: add LSM blob and hooks for namespaces
  2026-02-16 17:34 ` Casey Schaufler
@ 2026-02-17  9:38   ` Christian Brauner
  2026-02-17 17:29     ` Casey Schaufler
  2026-02-18 11:15     ` Dr. Greg
  0 siblings, 2 replies; 10+ messages in thread
From: Christian Brauner @ 2026-02-17  9:38 UTC (permalink / raw)
  To: Casey Schaufler
  Cc: Paul Moore, James Morris, linux-security-module, linux-kernel

On Mon, Feb 16, 2026 at 09:34:57AM -0800, Casey Schaufler wrote:
> On 2/16/2026 5:52 AM, Christian Brauner wrote:
> > All namespace types now share the same ns_common infrastructure. Extend
> > this to include a security blob so LSMs can start managing namespaces
> > uniformly without having to add one-off hooks or security fields to
> > every individual namespace type.
> 
> The implementation appears sound.
> 
> I have to question whether having LSM controls on namespaces is reasonable.

This is already in active use today but only in a very limited capacity.
This generalizes it.

> I suppose that you could have a system where (for example) SELinux runs
> in permissive mode except within a specific user namespace, where it would
> enforce policy. Do you have a use case in mind?

We will use it in systemd services and containers to monitor and
supervise namespaces.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH RFC] security: add LSM blob and hooks for namespaces
  2026-02-17  8:54   ` Christian Brauner
@ 2026-02-17 11:33     ` Paul Moore
  2026-03-12 10:10       ` Mickaël Salaün
  0 siblings, 1 reply; 10+ messages in thread
From: Paul Moore @ 2026-02-17 11:33 UTC (permalink / raw)
  To: Christian Brauner; +Cc: James Morris, linux-security-module, linux-kernel

On February 17, 2026 9:54:42 AM Christian Brauner <brauner@kernel.org> wrote:
> On Mon, Feb 16, 2026 at 07:53:11PM +0100, Paul Moore wrote:
>> On February 16, 2026 2:52:34 PM Christian Brauner <brauner@kernel.org> wrote:
>>> All namespace types now share the same ns_common infrastructure. Extend
>>> this to include a security blob so LSMs can start managing namespaces
>>> uniformly without having to add one-off hooks or security fields to
>>> every individual namespace type.
>>>
>>> Add a ns_security pointer to ns_common and the corresponding lbs_ns
>>> blob size to lsm_blob_sizes. Allocation and freeing hooks are called
>>> from the common __ns_common_init() and __ns_common_free() paths so
>>> every namespace type gets covered in one go. All information about the
>>> namespace type and the appropriate casting helpers to get at the
>>> containing namespace are available via ns_common making it
>>> straightforward for LSMs to differentiate when they need to.
>>>
>>> A namespace_install hook is called from validate_ns() during setns(2)
>>> giving LSMs a chance to enforce policy on namespace transitions.
>>>
>>> Individual namespace types can still have their own specialized security
>>> hooks when needed. This is just the common baseline that makes it easy
>>> to track and manage namespaces from the security side without requiring
>>> every namespace type to reinvent the wheel.
>>>
>>> Signed-off-by: Christian Brauner <brauner@kernel.org>
>>> ---
>>> include/linux/lsm_hook_defs.h      |  3 ++
>>> include/linux/lsm_hooks.h          |  1 +
>>> include/linux/ns/ns_common_types.h |  3 ++
>>> include/linux/security.h           | 20 ++++++++++
>>> kernel/nscommon.c                  | 12 ++++++
>>> kernel/nsproxy.c                   |  8 +++-
>>> security/lsm_init.c                |  2 +
>>> security/security.c                | 76 ++++++++++++++++++++++++++++++++++++++
>>> 8 files changed, 124 insertions(+), 1 deletion(-)
>>
>> I still have limited network access for a few more days, but a couple of
>> quick comments in no particular order ...
>>
>> Generally speaking we don't add things to the LSM interface without a user,
>> and I can't think of a good reason why we would want to do things
>> differently here.  This means that when you propose something like this you
>> should also propose an addition to one of the in-tree LSMs to make use of
>> it. While the guidance doc linked below (also linked in the LSM MAINTAINERS
>> entry) doesn't have any guidance for the LSM blobs as they are generally a
>> byproduct of the hooks, if you are looking for some general info I think the
>> bits on adding a new LSM hook would be very close to what we would expect
>> for blob additions.
>>
>> https://github.com/LinuxSecurityModule/kernel/blob/main/README.md
>>
>> Getting to the specifics of namespace related APIs, we've had a lot of
>> discussions about namespacing and my current opinion is that we need to sort
>> out if we want a userspace API at the LSM framework layer, or if we want to
>> do that at the individual LSM layer; there is a lot of nuance there and
>> while one option may seem like an obvious choice, we need some more
>> discussion and I need a chance to get caught up on the threads. Once we have
>> an API decision then we can start sorting out the implementation details
>> like the LSM blobs.
>
> I might be misunderstanding you but what you are talking about seems
> namespacing the LSM layer itself.
>
> But I cannot stress enough this is not at all what this patchset is
> doing. :)

Likely also a misunderstanding on my end as I triage email/patches via phone.

Regardless, the guidance in the doc I linked regarding the addition of new 
LSM hooks would appear to apply here.

--
paul-moore.com



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH RFC] security: add LSM blob and hooks for namespaces
  2026-02-17  9:38   ` Christian Brauner
@ 2026-02-17 17:29     ` Casey Schaufler
  2026-02-18 11:15     ` Dr. Greg
  1 sibling, 0 replies; 10+ messages in thread
From: Casey Schaufler @ 2026-02-17 17:29 UTC (permalink / raw)
  To: Christian Brauner
  Cc: Paul Moore, James Morris, linux-security-module, linux-kernel,
	Casey Schaufler

On 2/17/2026 1:38 AM, Christian Brauner wrote:
> On Mon, Feb 16, 2026 at 09:34:57AM -0800, Casey Schaufler wrote:
>> On 2/16/2026 5:52 AM, Christian Brauner wrote:
>>> All namespace types now share the same ns_common infrastructure. Extend
>>> this to include a security blob so LSMs can start managing namespaces
>>> uniformly without having to add one-off hooks or security fields to
>>> every individual namespace type.
>> The implementation appears sound.
>>
>> I have to question whether having LSM controls on namespaces is reasonable.
> This is already in active use today but only in a very limited capacity.
> This generalizes it.
>
>> I suppose that you could have a system where (for example) SELinux runs
>> in permissive mode except within a specific user namespace, where it would
>> enforce policy. Do you have a use case in mind?
> We will use it in systemd services and containers to monitor and
> supervise namespaces.

While I am not among them, many people have objected strongly to making
containers an identified entity in the kernel. If these hooks were available
implementing a container scheme completely within the kernel would be
reasonably strait forward. I might consider tackling it myself.

I am also reminded of the kdbus effort of a decade ago:

	https://www.linuxfoundation.org/blog/blog/kdbus-details

Are we ready for ksystemd? UNIX systems of the 1980's suffered greatly from
an excessive enthusiasm for pushing user space functionality (e.g. STREAMS)
into the kernel. Systemd is a fine scheme, but so was inittab, in a very
different way. Adding kernel facilities to support particular application
schemes is very tempting, but often leads to dead code and interfaces that
require maintenance long after the user space scheme has moved on.


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH RFC] security: add LSM blob and hooks for namespaces
  2026-02-17  9:38   ` Christian Brauner
  2026-02-17 17:29     ` Casey Schaufler
@ 2026-02-18 11:15     ` Dr. Greg
  1 sibling, 0 replies; 10+ messages in thread
From: Dr. Greg @ 2026-02-18 11:15 UTC (permalink / raw)
  To: Christian Brauner
  Cc: Casey Schaufler, Paul Moore, James Morris, linux-security-module,
	linux-kernel

On Tue, Feb 17, 2026 at 10:38:33AM +0100, Christian Brauner wrote:

Good morning, I hope the week is going well for everyone.

> On Mon, Feb 16, 2026 at 09:34:57AM -0800, Casey Schaufler wrote:
> > On 2/16/2026 5:52 AM, Christian Brauner wrote:
> > > All namespace types now share the same ns_common infrastructure. Extend
> > > this to include a security blob so LSMs can start managing namespaces
> > > uniformly without having to add one-off hooks or security fields to
> > > every individual namespace type.
> > 
> > The implementation appears sound.
> > 
> > I have to question whether having LSM controls on namespaces is reasonable.

> This is already in active use today but only in a very limited capacity.
> This generalizes it.

This seems to be a tacid indication of the need for namespace specific
LSM policies and/or controls, and further acknowledgement, that such
controls are in active use out in the wild.

More below on the implications of this.

> > I suppose that you could have a system where (for example) SELinux runs
> > in permissive mode except within a specific user namespace, where it would
> > enforce policy. Do you have a use case in mind?

> We will use it in systemd services and containers to monitor and
> supervise namespaces.

Christian, you are no doubt not familiar with our work, but over the
last six years our team has developed and have in production the most
sophisticated implementation of LSM namespacing that has been done.
With the caveat, of course, of implementations that have been made
public.

That work has been driven by what is the clear and apparent need to
have namespace specific and orthogonal security controls and policies,
something your patch and comments seems to clearly acknowledge.  This
need is particularily important with respect to the advancements that
are needed for AI based security modeling and interdiction.

So our comments are driven by having done a bit of this before.

There has been some dialogue and debate as to whether and how LSM
namespacing should be implemented.  The essential ingredient is the
need to have a task specific context of data, which can be inherited
by subordinate processes, that can be used to evaluate the LSM
security events/hooks that are executed by tasks having access to
that context of data.

Unless we misinterpret the implementation, your patch provides such
context for any process that wishes to unshare any namespace that it
is participating in.

This in turn implies that your patch is a fundamental step forward in
LSM namespacing.  This isn't a criticism, just an observation.

The reason we can feel pretty strongly about this is that we initially
used the same strategy that you are using in a very early
implementation of TSEM.  We abandoned that approach, since the
dynamics/politics of Linux kernel development, particularily in
security, tends to disfavor having to touch core kernel
infrastructure, so we implemented the equivalent of your approach
entirely in the context of our LSM.

To widen the scope of the impact of this, your patch also lays the
framework for implementing LSM specific security policy with kernel
modules.  Again, not a criticism, just an observation, because we
implement the same capability with TSEM.

For those reading along at home.  The reason that this is safe with a
classic namespace approach and not with previous 'loadable LSM'
strategies is that a process can verify that a policy module is loaded
and prepared to handle requests to interpret the events, before the
namespace installation/activation that would drive use of the module
actually takes effect.

Your approach is quite generic, which is positive. The open question
is whether or not the strategy is generic enough to handle LSM's that
may have very dynamic and varied requirements with respect to how to
configure the policy that will be implemented for the namespace.

Hopefully all of this will enable further discussions on this issue.

Best wishes for a productive remainder of the week.

As always,
Dr. Greg

The Quixote Project - Flailing at the Travails of Cybersecurity
              https://github.com/Quixote-Project


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH RFC] security: add LSM blob and hooks for namespaces
  2026-02-17 11:33     ` Paul Moore
@ 2026-03-12 10:10       ` Mickaël Salaün
  2026-03-18 20:17         ` danieldurning.work
  0 siblings, 1 reply; 10+ messages in thread
From: Mickaël Salaün @ 2026-03-12 10:10 UTC (permalink / raw)
  To: Paul Moore
  Cc: Christian Brauner, James Morris, linux-security-module,
	linux-kernel

On Tue, Feb 17, 2026 at 12:33:28PM +0100, Paul Moore wrote:
> On February 17, 2026 9:54:42 AM Christian Brauner <brauner@kernel.org> wrote:
> > On Mon, Feb 16, 2026 at 07:53:11PM +0100, Paul Moore wrote:
> > > On February 16, 2026 2:52:34 PM Christian Brauner <brauner@kernel.org> wrote:
> > > > All namespace types now share the same ns_common infrastructure. Extend
> > > > this to include a security blob so LSMs can start managing namespaces
> > > > uniformly without having to add one-off hooks or security fields to
> > > > every individual namespace type.
> > > > 
> > > > Add a ns_security pointer to ns_common and the corresponding lbs_ns
> > > > blob size to lsm_blob_sizes. Allocation and freeing hooks are called
> > > > from the common __ns_common_init() and __ns_common_free() paths so
> > > > every namespace type gets covered in one go. All information about the
> > > > namespace type and the appropriate casting helpers to get at the
> > > > containing namespace are available via ns_common making it
> > > > straightforward for LSMs to differentiate when they need to.
> > > > 
> > > > A namespace_install hook is called from validate_ns() during setns(2)
> > > > giving LSMs a chance to enforce policy on namespace transitions.
> > > > 
> > > > Individual namespace types can still have their own specialized security
> > > > hooks when needed. This is just the common baseline that makes it easy
> > > > to track and manage namespaces from the security side without requiring
> > > > every namespace type to reinvent the wheel.
> > > > 
> > > > Signed-off-by: Christian Brauner <brauner@kernel.org>
> > > > ---
> > > > include/linux/lsm_hook_defs.h      |  3 ++
> > > > include/linux/lsm_hooks.h          |  1 +
> > > > include/linux/ns/ns_common_types.h |  3 ++
> > > > include/linux/security.h           | 20 ++++++++++
> > > > kernel/nscommon.c                  | 12 ++++++
> > > > kernel/nsproxy.c                   |  8 +++-
> > > > security/lsm_init.c                |  2 +
> > > > security/security.c                | 76 ++++++++++++++++++++++++++++++++++++++
> > > > 8 files changed, 124 insertions(+), 1 deletion(-)
> > > 
> > > I still have limited network access for a few more days, but a couple of
> > > quick comments in no particular order ...
> > > 
> > > Generally speaking we don't add things to the LSM interface without a user,
> > > and I can't think of a good reason why we would want to do things
> > > differently here.  This means that when you propose something like this you
> > > should also propose an addition to one of the in-tree LSMs to make use of
> > > it. While the guidance doc linked below (also linked in the LSM MAINTAINERS
> > > entry) doesn't have any guidance for the LSM blobs as they are generally a
> > > byproduct of the hooks, if you are looking for some general info I think the
> > > bits on adding a new LSM hook would be very close to what we would expect
> > > for blob additions.
> > > 
> > > https://github.com/LinuxSecurityModule/kernel/blob/main/README.md
> > > 
> > > Getting to the specifics of namespace related APIs, we've had a lot of
> > > discussions about namespacing and my current opinion is that we need to sort
> > > out if we want a userspace API at the LSM framework layer, or if we want to
> > > do that at the individual LSM layer; there is a lot of nuance there and
> > > while one option may seem like an obvious choice, we need some more
> > > discussion and I need a chance to get caught up on the threads. Once we have
> > > an API decision then we can start sorting out the implementation details
> > > like the LSM blobs.
> > 
> > I might be misunderstanding you but what you are talking about seems
> > namespacing the LSM layer itself.
> > 
> > But I cannot stress enough this is not at all what this patchset is
> > doing. :)
> 
> Likely also a misunderstanding on my end as I triage email/patches via phone.
> 
> Regardless, the guidance in the doc I linked regarding the addition of new
> LSM hooks would appear to apply here.

FYI, I just sent an RFC to leverage this patch with Landlock:
https://lore.kernel.org/all/20260312100444.2609563-1-mic@digikod.net/

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH RFC] security: add LSM blob and hooks for namespaces
  2026-03-12 10:10       ` Mickaël Salaün
@ 2026-03-18 20:17         ` danieldurning.work
  0 siblings, 0 replies; 10+ messages in thread
From: danieldurning.work @ 2026-03-18 20:17 UTC (permalink / raw)
  To: brauner; +Cc: mic, jmorris, linux-kernel, linux-security-module, paul

On Thu, Mar 12, 2026, at 11:10:32AM +0100, Mickaël Salaün <mic@digikod.net> wrote:
> On Tue, Feb 17, 2026 at 12:33:28PM +0100, Paul Moore wrote:
> > On February 17, 2026 9:54:42 AM Christian Brauner <brauner@kernel.org> wrote:
> > > On Mon, Feb 16, 2026 at 07:53:11PM +0100, Paul Moore wrote:
> > > > On February 16, 2026 2:52:34 PM Christian Brauner <brauner@kernel.org> wrote:
> > > > > All namespace types now share the same ns_common infrastructure. Extend
> > > > > this to include a security blob so LSMs can start managing namespaces
> > > > > uniformly without having to add one-off hooks or security fields to
> > > > > every individual namespace type.
> > > > >
> > > > > Add a ns_security pointer to ns_common and the corresponding lbs_ns
> > > > > blob size to lsm_blob_sizes. Allocation and freeing hooks are called
> > > > > from the common __ns_common_init() and __ns_common_free() paths so
> > > > > every namespace type gets covered in one go. All information about the
> > > > > namespace type and the appropriate casting helpers to get at the
> > > > > containing namespace are available via ns_common making it
> > > > > straightforward for LSMs to differentiate when they need to.
> > > > >
> > > > > A namespace_install hook is called from validate_ns() during setns(2)
> > > > > giving LSMs a chance to enforce policy on namespace transitions.
> > > > >
> > > > > Individual namespace types can still have their own specialized security
> > > > > hooks when needed. This is just the common baseline that makes it easy
> > > > > to track and manage namespaces from the security side without requiring
> > > > > every namespace type to reinvent the wheel.
> > > > >
> > > > > Signed-off-by: Christian Brauner <brauner@kernel.org>
> > > > > ---
> > > > > include/linux/lsm_hook_defs.h      |  3 ++
> > > > > include/linux/lsm_hooks.h          |  1 +
> > > > > include/linux/ns/ns_common_types.h |  3 ++
> > > > > include/linux/security.h           | 20 ++++++++++
> > > > > kernel/nscommon.c                  | 12 ++++++
> > > > > kernel/nsproxy.c                   |  8 +++-
> > > > > security/lsm_init.c                |  2 +
> > > > > security/security.c                | 76 ++++++++++++++++++++++++++++++++++++++
> > > > > 8 files changed, 124 insertions(+), 1 deletion(-)
> > > >
> > > > I still have limited network access for a few more days, but a couple of
> > > > quick comments in no particular order ...
> > > >
> > > > Generally speaking we don't add things to the LSM interface without a user,
> > > > and I can't think of a good reason why we would want to do things
> > > > differently here.  This means that when you propose something like this you
> > > > should also propose an addition to one of the in-tree LSMs to make use of
> > > > it. While the guidance doc linked below (also linked in the LSM MAINTAINERS
> > > > entry) doesn't have any guidance for the LSM blobs as they are generally a
> > > > byproduct of the hooks, if you are looking for some general info I think the
> > > > bits on adding a new LSM hook would be very close to what we would expect
> > > > for blob additions.
> > > >
> > > > https://github.com/LinuxSecurityModule/kernel/blob/main/README.md
> > > >
> > > > Getting to the specifics of namespace related APIs, we've had a lot of
> > > > discussions about namespacing and my current opinion is that we need to sort
> > > > out if we want a userspace API at the LSM framework layer, or if we want to
> > > > do that at the individual LSM layer; there is a lot of nuance there and
> > > > while one option may seem like an obvious choice, we need some more
> > > > discussion and I need a chance to get caught up on the threads. Once we have
> > > > an API decision then we can start sorting out the implementation details
> > > > like the LSM blobs.
> > >
> > > I might be misunderstanding you but what you are talking about seems
> > > namespacing the LSM layer itself.
> > >
> > > But I cannot stress enough this is not at all what this patchset is
> > > doing. :)
> >
> > Likely also a misunderstanding on my end as I triage email/patches via phone.
> >
> > Regardless, the guidance in the doc I linked regarding the addition of new
> > LSM hooks would appear to apply here.
>
> FYI, I just sent an RFC to leverage this patch with Landlock:
> https://lore.kernel.org/all/20260312100444.2609563-1-mic@digikod.net/

I was working on an SELinux implementation of these hooks as well.
However, I noticed that when a mount namespace is created as anon
the security blob is allocated but never freed. The free_mnt_ns()
function only calls ns_common_free() if a mount namespace is not
marked as anon. This seems to be causing a memory leak.

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2026-03-18 20:20 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-16 13:52 [PATCH RFC] security: add LSM blob and hooks for namespaces Christian Brauner
2026-02-16 17:34 ` Casey Schaufler
2026-02-17  9:38   ` Christian Brauner
2026-02-17 17:29     ` Casey Schaufler
2026-02-18 11:15     ` Dr. Greg
2026-02-16 18:53 ` Paul Moore
2026-02-17  8:54   ` Christian Brauner
2026-02-17 11:33     ` Paul Moore
2026-03-12 10:10       ` Mickaël Salaün
2026-03-18 20:17         ` danieldurning.work

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox