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,
	Stephen Smalley <stephen.smalley.work@gmail.com>
Subject: [PATCH v3 15/42] selinux: introduce a global SID table
Date: Tue, 20 May 2025 07:59:13 -0400	[thread overview]
Message-ID: <20250520120000.25501-17-stephen.smalley.work@gmail.com> (raw)
In-Reply-To: <20250520120000.25501-2-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 83846fdaa3ad..9531f4c31766 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -105,6 +105,7 @@
 #include "netlabel.h"
 #include "audit.h"
 #include "avc_ss.h"
+#include "global_sidtab.h"
 
 #define SELINUX_INODE_INIT_XATTRS 1
 
@@ -7915,6 +7916,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.49.0


  parent reply	other threads:[~2025-05-20 12:01 UTC|newest]

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