summaryrefslogtreecommitdiff
path: root/security
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2026-09-07 14:27:31 +0100
committerMark Brown <broonie@kernel.org>2026-09-07 14:27:31 +0100
commit43208f9c83d6af9b026dfcddf7bc3bb658d75ae5 (patch)
treece4c4f6d81dfd6da649b4b5b42c3de45e0f89b70 /security
parent177134b13ae6bbcb1a5235e3199e41d821559ccd (diff)
parent3a84fc1a21577dbc8da7e4b6a49c9d8b07c07000 (diff)
downloadlinux-next-43208f9c83d6af9b026dfcddf7bc3bb658d75ae5.tar.gz
linux-next-43208f9c83d6af9b026dfcddf7bc3bb658d75ae5.zip
Merge branch 'next' of https://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/lsm.git
# Conflicts: # include/linux/ns/ns_common_types.h
Diffstat (limited to 'security')
-rw-r--r--security/lsm_audit.c6
-rw-r--r--security/lsm_init.c6
-rw-r--r--security/security.c75
3 files changed, 81 insertions, 6 deletions
diff --git a/security/lsm_audit.c b/security/lsm_audit.c
index 737f5a263a8f..29116ef2986b 100644
--- a/security/lsm_audit.c
+++ b/security/lsm_audit.c
@@ -182,7 +182,7 @@ void audit_log_lsm_data(struct audit_buffer *ab,
* start making this union too large! See struct lsm_network_audit
* as an example of how to deal with large data.
*/
- BUILD_BUG_ON(sizeof(a->u) > sizeof(void *)*2);
+ BUILD_BUG_ON(sizeof(a->u) > (sizeof(u64) * 2));
switch (a->type) {
case LSM_AUDIT_DATA_NONE:
@@ -403,6 +403,10 @@ void audit_log_lsm_data(struct audit_buffer *ab,
case LSM_AUDIT_DATA_NLMSGTYPE:
audit_log_format(ab, " nl-msgtype=%hu", a->u.nlmsg_type);
break;
+ case LSM_AUDIT_DATA_NS:
+ audit_log_format(ab, " namespace_type=0x%x namespace_id=%llu",
+ a->u.ns.ns_type, a->u.ns.ns_id);
+ break;
} /* switch (a->type) */
}
diff --git a/security/lsm_init.c b/security/lsm_init.c
index a1ad641811de..dbda7771013b 100644
--- a/security/lsm_init.c
+++ b/security/lsm_init.c
@@ -290,7 +290,6 @@ static void __init lsm_prepare(struct lsm_info *lsm)
return;
/* Register the LSM blob sizes. */
- blobs = lsm->blobs;
lsm_blob_size_update(&blobs->lbs_cred, &blob_sizes.lbs_cred);
lsm_blob_size_update(&blobs->lbs_file, &blob_sizes.lbs_file);
lsm_blob_size_update(&blobs->lbs_backing_file,
@@ -303,6 +302,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);
@@ -450,6 +450,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);
@@ -476,8 +477,7 @@ int __init security_init(void)
blob_sizes.lbs_inode, 0,
SLAB_PANIC, NULL);
- if (lsm_cred_alloc((struct cred *)unrcu_pointer(current->cred),
- GFP_KERNEL))
+ if (lsm_cred_alloc((struct cred *)current->cred, GFP_KERNEL))
panic("early LSM cred alloc failed\n");
if (lsm_task_alloc(current))
panic("early LSM task alloc failed\n");
diff --git a/security/security.c b/security/security.c
index 2ee276ab15c5..ecfb875f0c69 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>
@@ -382,6 +383,19 @@ static int lsm_superblock_alloc(struct super_block *sb)
}
/**
+ * 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
* @uctx_len: available uctx size (input), used uctx size (output)
@@ -2486,9 +2500,8 @@ void security_backing_file_free(struct file *backing_file)
{
void *blob = backing_file_security(backing_file);
- call_void_hook(backing_file_free, backing_file);
-
if (blob) {
+ call_void_hook(backing_file_free, backing_file);
backing_file_set_security(backing_file, NULL);
kmem_cache_free(lsm_backing_file_cache, blob);
}
@@ -3358,6 +3371,64 @@ int security_create_user_ns(const struct cred *cred)
}
/**
+ * security_namespace_init() - Initialize LSM security data for a namespace
+ * @ns: the namespace being initialized
+ *
+ * Initialize the LSM security blob attached 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_init(struct ns_common *ns)
+{
+ int rc;
+
+ rc = lsm_ns_alloc(ns);
+ if (unlikely(rc))
+ return rc;
+
+ rc = call_int_hook(namespace_init, 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.
+ */
+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
* @flag: requested permissions