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 v4 26/42] selinux: introduce cred_ssid_has_perm() and cred_other_has_perm()
Date: Tue, 10 Jun 2025 13:21:57 -0400	[thread overview]
Message-ID: <20250610172226.1470741-27-stephen.smalley.work@gmail.com> (raw)
In-Reply-To: <20250610172226.1470741-1-stephen.smalley.work@gmail.com>

Introduce cred_ssid_has_perm() for checking permissions between
a fixed (source SID, target SID) pair against the current SELinux
namespace and all ancestors. This helper is appropriate for
checks between two object SIDs, but should NOT be used
when dealing with task/cred objects.

Introduce cred_other_has_perm() for checking permissions between
two creds against the current SELinux namespace and all
ancestors.

Convert permission checks of these two forms in the hook functions
to use these new namespace-aware helpers.

Signed-off-by: Stephen Smalley <stephen.smalley.work@gmail.com>
---
 security/selinux/avc.c         | 62 ++++++++++++++++++++++++++++++++++
 security/selinux/hooks.c       | 61 +++++++++++++--------------------
 security/selinux/include/avc.h |  7 ++++
 3 files changed, 93 insertions(+), 37 deletions(-)

diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index 1d1a6fdafa7d..9385dcd84eee 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -1417,6 +1417,68 @@ int cred_has_perm_noaudit(const struct cred *cred, u32 tsid, u16 tclass,
 	return 0;
 }
 
+int cred_ssid_has_perm(const struct cred *cred, u32 ssid, u32 tsid, u16 tclass,
+		       u32 requested, struct common_audit_data *ad)
+{
+	struct task_security_struct *tsec;
+	struct selinux_state *state;
+	int rc;
+
+	do {
+		tsec = selinux_cred(cred);
+		state = tsec->state;
+		rc = avc_has_perm(state, ssid, tsid, tclass, requested, ad);
+		if (rc)
+			return rc;
+
+		cred = tsec->parent_cred;
+	} while (cred);
+
+	return 0;
+}
+
+static u32 cred_sid_for_state(const struct cred *cred,
+			      const struct selinux_state *state)
+{
+	const struct task_security_struct *tsec;
+	u32 sid;
+
+	tsec = selinux_cred(cred);
+	while (tsec->state != state && tsec->parent_cred)
+		tsec = selinux_cred(tsec->parent_cred);
+	if (tsec->state == state)
+		sid = tsec->sid;
+	else
+		sid = SECINITSID_UNLABELED;
+	return sid;
+}
+
+int cred_other_has_perm(const struct cred *cred, const struct cred *other,
+			u16 tclass, u32 requested,
+			struct common_audit_data *ad)
+{
+	struct task_security_struct *tsec;
+	struct selinux_state *state;
+	u32 ssid;
+	u32 tsid;
+	int rc;
+
+	do {
+		tsec = selinux_cred(cred);
+		ssid = tsec->sid;
+		state = tsec->state;
+		tsid = cred_sid_for_state(other, state);
+
+		rc = avc_has_perm(state, ssid, tsid, tclass, requested, ad);
+		if (rc)
+			return rc;
+
+		cred = tsec->parent_cred;
+	} while (cred);
+
+	return 0;
+}
+
 u32 avc_policy_seqno(struct selinux_state *state)
 {
 	return state->avc->avc_cache.latest_notif;
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index c0a04774fd27..4c2f7491803b 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -469,9 +469,8 @@ static int may_context_mount_inode_relabel(u32 sid,
 	if (rc)
 		return rc;
 
-	return avc_has_perm(cred_selinux_state(cred),
-			    sid, sbsec->sid, SECCLASS_FILESYSTEM,
-			    FILESYSTEM__ASSOCIATE, NULL);
+	return cred_ssid_has_perm(cred, sid, sbsec->sid, SECCLASS_FILESYSTEM,
+				  FILESYSTEM__ASSOCIATE, NULL);
 }
 
 static int selinux_is_genfs_special_handling(struct super_block *sb)
@@ -1858,10 +1857,9 @@ static int may_create(struct inode *dir,
 	if (rc)
 		return rc;
 
-	return avc_has_perm(current_selinux_state,
-			    newsid, sbsec->sid,
-			    SECCLASS_FILESYSTEM,
-			    FILESYSTEM__ASSOCIATE, &ad);
+	return cred_ssid_has_perm(cred, newsid, sbsec->sid,
+				  SECCLASS_FILESYSTEM, FILESYSTEM__ASSOCIATE,
+				  &ad);
 }
 
 #define MAY_LINK	0
@@ -2050,9 +2048,8 @@ static inline u32 open_file_to_av(struct file *file)
 
 static int selinux_binder_set_context_mgr(const struct cred *mgr)
 {
-	return avc_has_perm(current_selinux_state,
-			    current_sid(), cred_sid(mgr), SECCLASS_BINDER,
-			    BINDER__SET_CONTEXT_MGR, NULL);
+	return cred_other_has_perm(current_cred(), mgr, SECCLASS_BINDER,
+				   BINDER__SET_CONTEXT_MGR, NULL);
 }
 
 static int selinux_binder_transaction(const struct cred *from,
@@ -2060,28 +2057,25 @@ static int selinux_binder_transaction(const struct cred *from,
 {
 	u32 mysid = current_sid();
 	u32 fromsid = cred_sid(from);
-	u32 tosid = cred_sid(to);
 	int rc;
 
 	if (mysid != fromsid) {
-		rc = avc_has_perm(cred_selinux_state(from),
-				  mysid, fromsid, SECCLASS_BINDER,
-				  BINDER__IMPERSONATE, NULL);
+		rc = cred_other_has_perm(current_cred(), from,
+					 SECCLASS_BINDER,
+					 BINDER__IMPERSONATE, NULL);
 		if (rc)
 			return rc;
 	}
 
-	return avc_has_perm(cred_selinux_state(from), fromsid, tosid,
-			    SECCLASS_BINDER, BINDER__CALL, NULL);
+	return cred_other_has_perm(from, to, SECCLASS_BINDER, BINDER__CALL,
+				   NULL);
 }
 
 static int selinux_binder_transfer_binder(const struct cred *from,
 					  const struct cred *to)
 {
-	return avc_has_perm(current_selinux_state,
-			    cred_sid(from), cred_sid(to),
-			    SECCLASS_BINDER, BINDER__TRANSFER,
-			    NULL);
+	return cred_other_has_perm(from, to, SECCLASS_BINDER,
+				   BINDER__TRANSFER, NULL);
 }
 
 static int selinux_binder_transfer_file(const struct cred *from,
@@ -2149,9 +2143,8 @@ static int selinux_capset(struct cred *new, const struct cred *old,
 			  const kernel_cap_t *inheritable,
 			  const kernel_cap_t *permitted)
 {
-	return avc_has_perm(cred_selinux_state(old),
-			    cred_sid(old), cred_sid(new), SECCLASS_PROCESS,
-			    PROCESS__SETCAP, NULL);
+	return cred_other_has_perm(old, new, SECCLASS_PROCESS,
+				   PROCESS__SETCAP, NULL);
 }
 
 /*
@@ -3412,12 +3405,9 @@ static int selinux_inode_setxattr(struct mnt_idmap *idmap,
 	if (rc)
 		return rc;
 
-	return avc_has_perm(current_selinux_state,
-			    newsid,
-			    sbsec->sid,
-			    SECCLASS_FILESYSTEM,
-			    FILESYSTEM__ASSOCIATE,
-			    &ad);
+	return cred_ssid_has_perm(cred, newsid, sbsec->sid,
+				  SECCLASS_FILESYSTEM,
+				  FILESYSTEM__ASSOCIATE, &ad);
 }
 
 static int selinux_inode_set_acl(struct mnt_idmap *idmap,
@@ -4428,9 +4418,7 @@ static int selinux_task_prlimit(const struct cred *cred, const struct cred *tcre
 		av |= PROCESS__SETRLIMIT;
 	if (flags & LSM_PRLIMIT_READ)
 		av |= PROCESS__GETRLIMIT;
-	return avc_has_perm(cred_selinux_state(cred),
-			    cred_sid(cred), cred_sid(tcred),
-			    SECCLASS_PROCESS, av, NULL);
+	return cred_other_has_perm(cred, tcred, SECCLASS_PROCESS, av, NULL);
 }
 
 static int selinux_task_setrlimit(struct task_struct *p, unsigned int resource,
@@ -6362,9 +6350,8 @@ static int selinux_msg_queue_msgsnd(struct kern_ipc_perm *msq, struct msg_msg *m
 				   &ad);
 	if (!rc)
 		/* Can the message be put in the queue? */
-		rc = avc_has_perm(current_selinux_state,
-				  msec->sid, isec->sid, SECCLASS_MSGQ,
-				  MSGQ__ENQUEUE, &ad);
+		rc = cred_ssid_has_perm(cred, msec->sid, isec->sid,
+					SECCLASS_MSGQ, MSGQ__ENQUEUE, &ad);
 
 	return rc;
 }
@@ -7319,8 +7306,8 @@ static int selinux_perf_event_write(struct perf_event *event)
  */
 static int selinux_uring_override_creds(const struct cred *new)
 {
-	return avc_has_perm(current_selinux_state, current_sid(), cred_sid(new),
-			    SECCLASS_IO_URING, IO_URING__OVERRIDE_CREDS, NULL);
+	return cred_other_has_perm(current_cred(), new, SECCLASS_IO_URING,
+				   IO_URING__OVERRIDE_CREDS, NULL);
 }
 
 /**
diff --git a/security/selinux/include/avc.h b/security/selinux/include/avc.h
index 106c511db114..1631f6cdbefd 100644
--- a/security/selinux/include/avc.h
+++ b/security/selinux/include/avc.h
@@ -166,6 +166,13 @@ int cred_has_perm(const struct cred *cred, u32 tsid, u16 tclass, u32 requested,
 int cred_has_perm_noaudit(const struct cred *cred, u32 tsid, u16 tclass,
 			  u32 requested, struct av_decision *avd);
 
+int cred_ssid_has_perm(const struct cred *cred, u32 ssid, u32 tsid, u16 tclass,
+		       u32 requested, struct common_audit_data *ad);
+
+int cred_other_has_perm(const struct cred *cred, const struct cred *other,
+			u16 tclass, u32 requested,
+			struct common_audit_data *ad);
+
 u32 avc_policy_seqno(struct selinux_state *state);
 
 #define AVC_CALLBACK_GRANT		1
-- 
2.49.0


  parent reply	other threads:[~2025-06-10 17:23 UTC|newest]

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