netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Stephen Smalley <stephen.smalley.work@gmail.com>
To: selinux@vger.kernel.org
Cc: paul@paul-moore.com, omosnace@redhat.com, netdev@vger.kernel.org,
	horms@kernel.org,
	Stephen Smalley <stephen.smalley.work@gmail.com>
Subject: [PATCH v7 16/42] selinux: introduce a global SID table
Date: Thu, 14 Aug 2025 09:26:07 -0400	[thread overview]
Message-ID: <20250814132637.1659-17-stephen.smalley.work@gmail.com> (raw)
In-Reply-To: <20250814132637.1659-1-stephen.smalley.work@gmail.com>

Introduce a global SID table to provide stable global SID values
independent of any particular policy or namespace. This table will only
map between global SIDs and security context strings since it must
remain policy-independent. Internally each of these global SIDs can then
be mapped on a per-policy/namespace basis to per-namespace SIDs and
context structures. The LSM interfaces and blob structures will only use
the global SID values and thus remain namespace-neutral.

Note that this required moving the SID table header and its dependencies
out of the security server subdirectory. While we could re-factor it to
to reduce the scope of this change, doing so does not seem worthwhile.
The security server abstraction is largely obsoleted by LSM, no one has
contributed any other security server implementation for SELinux, and
over time there has been an increasing blurring of the boundary between the
security server and the rest of the SELinux module. Eventually, I
anticipate fully moving the security server files out of the ss
subdirectory but that is left for a future change.

Signed-off-by: Stephen Smalley <stephen.smalley.work@gmail.com>
---
 security/selinux/Makefile                     |   2 +-
 security/selinux/global_sidtab.c              | 109 ++++++++++++++++++
 security/selinux/hooks.c                      |   4 +
 security/selinux/{ss => include}/avtab.h      |   0
 security/selinux/{ss => include}/constraint.h |   0
 security/selinux/{ss => include}/context.h    |   0
 security/selinux/{ss => include}/ebitmap.h    |   0
 security/selinux/include/global_sidtab.h      |  19 +++
 security/selinux/{ss => include}/hashtab.h    |   0
 security/selinux/{ss => include}/mls.h        |   0
 security/selinux/{ss => include}/mls_types.h  |   0
 security/selinux/{ss => include}/policydb.h   |   0
 security/selinux/{ss => include}/sidtab.h     |   0
 security/selinux/{ss => include}/symtab.h     |   0
 14 files changed, 133 insertions(+), 1 deletion(-)
 create mode 100644 security/selinux/global_sidtab.c
 rename security/selinux/{ss => include}/avtab.h (100%)
 rename security/selinux/{ss => include}/constraint.h (100%)
 rename security/selinux/{ss => include}/context.h (100%)
 rename security/selinux/{ss => include}/ebitmap.h (100%)
 create mode 100644 security/selinux/include/global_sidtab.h
 rename security/selinux/{ss => include}/hashtab.h (100%)
 rename security/selinux/{ss => include}/mls.h (100%)
 rename security/selinux/{ss => include}/mls_types.h (100%)
 rename security/selinux/{ss => include}/policydb.h (100%)
 rename security/selinux/{ss => include}/sidtab.h (100%)
 rename security/selinux/{ss => include}/symtab.h (100%)

diff --git a/security/selinux/Makefile b/security/selinux/Makefile
index 66e56e9011df..fe5f6f4bb0ea 100644
--- a/security/selinux/Makefile
+++ b/security/selinux/Makefile
@@ -15,7 +15,7 @@ ccflags-y := -I$(srctree)/security/selinux -I$(srctree)/security/selinux/include
 ccflags-$(CONFIG_SECURITY_SELINUX_DEBUG) += -DDEBUG
 
 selinux-y := avc.o hooks.o selinuxfs.o netlink.o nlmsgtab.o netif.o \
-	     netnode.o netport.o status.o \
+	     netnode.o netport.o status.o global_sidtab.o \
 	     ss/ebitmap.o ss/hashtab.o ss/symtab.o ss/sidtab.o ss/avtab.o \
 	     ss/policydb.o ss/services.o ss/conditional.o ss/mls.o ss/context.o
 
diff --git a/security/selinux/global_sidtab.c b/security/selinux/global_sidtab.c
new file mode 100644
index 000000000000..57866a2d4cc2
--- /dev/null
+++ b/security/selinux/global_sidtab.c
@@ -0,0 +1,109 @@
+// SPDX-License-Identifier: GPL-2.0
+#include "global_sidtab.h"
+#include "sidtab.h"
+
+static struct sidtab global_sidtab;
+
+int global_sidtab_init(void)
+{
+	struct context ctx;
+	int rc, sid;
+
+	rc = sidtab_init(&global_sidtab);
+	if (rc)
+		return rc;
+
+	memset(&ctx, 0, sizeof(ctx));
+	for (sid = 1; sid <= SECINITSID_NUM; sid++) {
+		const char *str = security_get_initial_sid_context(sid);
+
+		if (!str)
+			continue;
+		/*
+		 * Before the policy is loaded, translate
+		 * SECINITSID_INIT to "kernel", because systemd and
+		 * libselinux < 2.6 take a getcon_raw() result that is
+		 * both non-null and not "kernel" to mean that a policy
+		 * is already loaded.
+		 */
+		if (sid == SECINITSID_INIT)
+			str = "kernel";
+		ctx.str = (char *)str;
+		ctx.len = strlen(str)+1;
+		rc = sidtab_set_initial(&global_sidtab, sid, &ctx);
+		if (rc)
+			return rc;
+	}
+
+	return 0;
+}
+
+int global_sid_to_context(u32 sid, char **scontext, u32 *scontext_len)
+{
+	struct context *ctx;
+
+	rcu_read_lock();
+	ctx = sidtab_search_force(&global_sidtab, sid);
+	if (!ctx) {
+		rcu_read_unlock();
+		*scontext = NULL;
+		*scontext_len = 0;
+		return -EINVAL;
+	}
+	*scontext_len = ctx->len;
+	/*
+	 * Could eliminate allocation + copy if callers do not free
+	 * since the global sidtab entries are never freed.
+	 * This however would not match the current expectation
+	 * of callers of security_sid_to_context().
+	 * TODO: Update all callers and get rid of this copy.
+	 */
+	*scontext = kstrdup(ctx->str, GFP_ATOMIC);
+	if (!(*scontext)) {
+		rcu_read_unlock();
+		*scontext_len = 0;
+		return -ENOMEM;
+	}
+
+	rcu_read_unlock();
+	return 0;
+}
+
+int global_context_to_sid(const char *scontext, u32 scontext_len, u32 *out_sid,
+			gfp_t gfp)
+{
+	char *str;
+	struct context ctx;
+	int rc;
+
+	if (!scontext_len)
+		return -EINVAL;
+
+	/*
+	 * Could eliminate allocation + copy if callers were required to
+	 * pass in a NUL-terminated string or if the context_cmp/cpy()
+	 * functions did not assume that ctx.str is NUL-terminated.
+	 * This however would not match the current expectation of
+	 * callers of security_context_to_sid, particularly contexts
+	 * fetched from xattr values or provided by the xattr APIs.
+	 * TODO: Change context_cmp/cpy() or update all callers and
+	 * get rid of this copy.
+	 */
+	str = kmemdup_nul(scontext, scontext_len, gfp);
+	if (!str)
+		return -ENOMEM;
+
+	ctx.str = str;
+	ctx.len = strlen(str)+1;
+
+retry:
+	rcu_read_lock();
+	rc = sidtab_context_to_sid(&global_sidtab, &ctx, out_sid);
+	if (rc == -ESTALE) {
+		rcu_read_unlock();
+		goto retry;
+	}
+	rcu_read_unlock();
+	kfree(str);
+	return rc;
+}
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 145432020575..e84f3a1e3e12 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -104,6 +104,7 @@
 #include "netlabel.h"
 #include "audit.h"
 #include "avc_ss.h"
+#include "global_sidtab.h"
 
 #define SELINUX_INODE_INIT_XATTRS 1
 
@@ -7911,6 +7912,9 @@ static __init int selinux_init(void)
 
 	enforcing_set(init_selinux_state, selinux_enforcing_boot);
 
+	if (global_sidtab_init())
+		panic("SELinux: Could not create global SID table\n");
+
 	default_noexec = !(VM_DATA_DEFAULT_FLAGS & VM_EXEC);
 	if (!default_noexec)
 		pr_notice("SELinux:  virtual memory is executable by default\n");
diff --git a/security/selinux/ss/avtab.h b/security/selinux/include/avtab.h
similarity index 100%
rename from security/selinux/ss/avtab.h
rename to security/selinux/include/avtab.h
diff --git a/security/selinux/ss/constraint.h b/security/selinux/include/constraint.h
similarity index 100%
rename from security/selinux/ss/constraint.h
rename to security/selinux/include/constraint.h
diff --git a/security/selinux/ss/context.h b/security/selinux/include/context.h
similarity index 100%
rename from security/selinux/ss/context.h
rename to security/selinux/include/context.h
diff --git a/security/selinux/ss/ebitmap.h b/security/selinux/include/ebitmap.h
similarity index 100%
rename from security/selinux/ss/ebitmap.h
rename to security/selinux/include/ebitmap.h
diff --git a/security/selinux/include/global_sidtab.h b/security/selinux/include/global_sidtab.h
new file mode 100644
index 000000000000..f62a9165d26a
--- /dev/null
+++ b/security/selinux/include/global_sidtab.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * A global security identifier table (sidtab) is a lookup table
+ * of security context strings indexed by SID value.
+ */
+
+#ifndef _GLOBAL_SIDTAB_H_
+#define _GLOBAL_SIDTAB_H_
+
+#include <linux/types.h>
+
+extern int global_sidtab_init(void);
+
+extern int global_sid_to_context(u32 sid, char **scontext, u32 *scontext_len);
+
+extern int global_context_to_sid(const char *scontext, u32 scontext_len,
+				 u32 *out_sid, gfp_t gfp);
+
+#endif /* _GLOBAL_SIDTAB_H_ */
diff --git a/security/selinux/ss/hashtab.h b/security/selinux/include/hashtab.h
similarity index 100%
rename from security/selinux/ss/hashtab.h
rename to security/selinux/include/hashtab.h
diff --git a/security/selinux/ss/mls.h b/security/selinux/include/mls.h
similarity index 100%
rename from security/selinux/ss/mls.h
rename to security/selinux/include/mls.h
diff --git a/security/selinux/ss/mls_types.h b/security/selinux/include/mls_types.h
similarity index 100%
rename from security/selinux/ss/mls_types.h
rename to security/selinux/include/mls_types.h
diff --git a/security/selinux/ss/policydb.h b/security/selinux/include/policydb.h
similarity index 100%
rename from security/selinux/ss/policydb.h
rename to security/selinux/include/policydb.h
diff --git a/security/selinux/ss/sidtab.h b/security/selinux/include/sidtab.h
similarity index 100%
rename from security/selinux/ss/sidtab.h
rename to security/selinux/include/sidtab.h
diff --git a/security/selinux/ss/symtab.h b/security/selinux/include/symtab.h
similarity index 100%
rename from security/selinux/ss/symtab.h
rename to security/selinux/include/symtab.h
-- 
2.50.1


  parent reply	other threads:[~2025-08-14 13:27 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-08-14 13:25 [PATCH v7 00/42] SELinux namespace support Stephen Smalley
2025-08-14 13:25 ` [PATCH v7 01/42] selinux: restore passing of selinux_state Stephen Smalley
2025-08-14 13:25 ` [PATCH v7 02/42] selinux: introduce current_selinux_state Stephen Smalley
2025-08-14 13:25 ` [PATCH v7 03/42] selinux: support multiple selinuxfs instances Stephen Smalley
2025-08-14 13:25 ` [PATCH v7 04/42] selinux: dynamically allocate selinux namespace Stephen Smalley
2025-08-14 13:25 ` [PATCH v7 05/42] netstate,selinux: create the selinux netlink socket per network namespace Stephen Smalley
2025-08-14 13:25 ` [PATCH v7 06/42] selinux: limit selinux netlink notifications to init namespace Stephen Smalley
2025-08-14 13:25 ` [PATCH v7 07/42] selinux: support per-task/cred selinux namespace Stephen Smalley
2025-08-14 13:25 ` [PATCH v7 08/42] selinux: introduce cred_selinux_state() and use it Stephen Smalley
2025-08-14 13:26 ` [PATCH v7 09/42] selinux: init inode from nearest initialized namespace Stephen Smalley
2025-08-14 13:26 ` [PATCH v7 10/42] selinux: add a selinuxfs interface to unshare selinux namespace Stephen Smalley
2025-08-14 13:26 ` [PATCH v7 11/42] selinux: add limits for SELinux namespaces Stephen Smalley
2025-08-14 13:26 ` [PATCH v7 12/42] selinux: exempt creation of init SELinux namespace from limits Stephen Smalley
2025-08-14 13:26 ` [PATCH v7 13/42] selinux: refactor selinux_state_create() Stephen Smalley
2025-08-14 13:26 ` [PATCH v7 14/42] selinux: allow userspace to detect non-init SELinux namespace Stephen Smalley
2025-08-14 13:26 ` [PATCH v7 15/42] selinuxfs: restrict write operations to the same selinux namespace Stephen Smalley
2025-08-14 13:26 ` Stephen Smalley [this message]
2025-08-14 13:26 ` [PATCH v7 17/42] selinux: wrap security server interfaces to use the global SID table Stephen Smalley
2025-08-14 13:26 ` [PATCH v7 18/42] selinux: introduce a Kconfig option for SELinux namespaces Stephen Smalley
2025-08-14 13:26 ` [PATCH v7 19/42] selinux: eliminate global SID table if !CONFIG_SECURITY_SELINUX_NS Stephen Smalley
2025-08-14 13:26 ` [PATCH v7 20/42] selinux: maintain a small cache in the global SID table Stephen Smalley
2025-08-14 13:26 ` [PATCH v7 21/42] selinux: update hook functions to use correct selinux namespace Stephen Smalley
2025-08-14 13:26 ` [PATCH v7 22/42] selinux: introduce cred_task_has_perm() Stephen Smalley
2025-08-14 13:26 ` [PATCH v7 23/42] selinux: introduce cred_has_extended_perms() Stephen Smalley
2025-08-14 13:26 ` [PATCH v7 24/42] selinux: introduce cred_self_has_perm() Stephen Smalley
2025-08-14 13:26 ` [PATCH v7 25/42] selinux: introduce cred_has_perm() Stephen Smalley
2025-08-14 13:26 ` [PATCH v7 26/42] selinux: introduce cred_ssid_has_perm() and cred_other_has_perm() Stephen Smalley
2025-08-14 13:26 ` [PATCH v7 27/42] selinux: introduce task_obj_has_perm() Stephen Smalley
2025-08-14 13:26 ` [PATCH v7 28/42] selinux: update bprm hooks for selinux namespaces Stephen Smalley
2025-08-14 13:26 ` [PATCH v7 29/42] selinux: add kerneldoc to new permission checking functions Stephen Smalley
2025-08-14 13:26 ` [PATCH v7 30/42] selinux: convert selinux_file_send_sigiotask() to namespace-aware helper Stephen Smalley
2025-08-14 13:26 ` [PATCH v7 31/42] selinux: rename cred_has_perm*() to cred_tsid_has_perm*() Stephen Smalley
2025-08-14 13:26 ` [PATCH v7 32/42] selinux: update cred_tsid_has_perm_noaudit() to return the combined avd Stephen Smalley
2025-08-14 13:26 ` [PATCH v7 33/42] selinux: convert additional checks to cred_ssid_has_perm() Stephen Smalley
2025-08-14 13:26 ` [PATCH v7 34/42] selinux: introduce selinux_state_has_perm() Stephen Smalley
2025-08-14 13:26 ` [PATCH v7 35/42] selinux: annotate selinuxfs permission checks Stephen Smalley
2025-08-14 13:26 ` [PATCH v7 36/42] selinux: annotate process transition " Stephen Smalley
2025-08-14 13:26 ` [PATCH v7 37/42] selinux: convert xfrm and netlabel " Stephen Smalley
2025-08-14 13:26 ` [PATCH v7 38/42] selinux: switch selinux_lsm_setattr() checks to current namespace Stephen Smalley
2025-08-14 13:26 ` [PATCH v7 39/42] selinux: make open_perms namespace-aware Stephen Smalley
2025-08-14 13:26 ` [PATCH v7 40/42] selinux: split cred_ssid_has_perm() into two cases Stephen Smalley
2025-08-14 13:26 ` [PATCH v7 41/42] selinux: convert nlmsg_sock_has_extended_perms() to namespace-aware Stephen Smalley
2025-08-14 13:26 ` [PATCH v7 42/42] selinux: disallow writes to /sys/fs/selinux/user in non-init namespaces Stephen Smalley

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250814132637.1659-17-stephen.smalley.work@gmail.com \
    --to=stephen.smalley.work@gmail.com \
    --cc=horms@kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=omosnace@redhat.com \
    --cc=paul@paul-moore.com \
    --cc=selinux@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).