Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 9 Jun 2025 23:48:01 GMT
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 0d5b6fb6aee8 - main - kern_prot: extract code to check that active ids are superset of obj ids
Message-ID:  <202506092348.559Nm1tK088753@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=0d5b6fb6aee8faff5265d429daaf61e7b79c5252

commit 0d5b6fb6aee8faff5265d429daaf61e7b79c5252
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2025-06-07 13:47:34 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2025-06-09 23:47:12 +0000

    kern_prot: extract code to check that active ids are superset of obj ids
    
    Export it as a helper cr_xids_subset().
    
    Reviewed by:    markj
    Sponsored by:   NVidia networking
    Differential revision:  https://reviews.freebsd.org/D50653
---
 sys/kern/kern_prot.c | 64 ++++++++++++++++++++++++++++++++--------------------
 sys/sys/ucred.h      |  1 +
 2 files changed, 40 insertions(+), 25 deletions(-)

diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c
index cc140d28e13d..d9aeec68e620 100644
--- a/sys/kern/kern_prot.c
+++ b/sys/kern/kern_prot.c
@@ -2150,6 +2150,43 @@ SYSCTL_PROC(_security_bsd, OID_AUTO, unprivileged_proc_debug,
     CTLFLAG_MPSAFE, 0, 0, sysctl_unprivileged_proc_debug, "I",
     "Unprivileged processes may use process debugging facilities");
 
+/*
+ * Return true if the object owner/group ids are subset of the active
+ * credentials.
+ */
+bool
+cr_xids_subset(struct ucred *active_cred, struct ucred *obj_cred)
+{
+	int i;
+	bool grpsubset, uidsubset;
+
+	/*
+	 * Is p's group set a subset of td's effective group set?  This
+	 * includes p's egid, group access list, rgid, and svgid.
+	 */
+	grpsubset = true;
+	for (i = 0; i < obj_cred->cr_ngroups; i++) {
+		if (!groupmember(obj_cred->cr_groups[i], active_cred)) {
+			grpsubset = false;
+			break;
+		}
+	}
+	grpsubset = grpsubset &&
+	    groupmember(obj_cred->cr_rgid, active_cred) &&
+	    groupmember(obj_cred->cr_svgid, active_cred);
+
+	/*
+	 * Are the uids present in obj_cred's credential equal to
+	 * active_cred's effective uid?  This includes obj_cred's
+	 * euid, svuid, and ruid.
+	 */
+	uidsubset = (active_cred->cr_uid == obj_cred->cr_uid &&
+	    active_cred->cr_uid == obj_cred->cr_svuid &&
+	    active_cred->cr_uid == obj_cred->cr_ruid);
+
+	return (uidsubset && grpsubset);
+}
+
 /*-
  * Determine whether td may debug p.
  * Returns: 0 for permitted, an errno value otherwise
@@ -2161,7 +2198,7 @@ SYSCTL_PROC(_security_bsd, OID_AUTO, unprivileged_proc_debug,
 int
 p_candebug(struct thread *td, struct proc *p)
 {
-	int error, grpsubset, i, uidsubset;
+	int error;
 
 	KASSERT(td == curthread, ("%s: td not curthread", __func__));
 	PROC_LOCK_ASSERT(p, MA_OWNED);
@@ -2178,35 +2215,12 @@ p_candebug(struct thread *td, struct proc *p)
 	if ((error = cr_bsd_visible(td->td_ucred, p->p_ucred)))
 		return (error);
 
-	/*
-	 * Is p's group set a subset of td's effective group set?  This
-	 * includes p's egid, group access list, rgid, and svgid.
-	 */
-	grpsubset = 1;
-	for (i = 0; i < p->p_ucred->cr_ngroups; i++) {
-		if (!groupmember(p->p_ucred->cr_groups[i], td->td_ucred)) {
-			grpsubset = 0;
-			break;
-		}
-	}
-	grpsubset = grpsubset &&
-	    groupmember(p->p_ucred->cr_rgid, td->td_ucred) &&
-	    groupmember(p->p_ucred->cr_svgid, td->td_ucred);
-
-	/*
-	 * Are the uids present in p's credential equal to td's
-	 * effective uid?  This includes p's euid, svuid, and ruid.
-	 */
-	uidsubset = (td->td_ucred->cr_uid == p->p_ucred->cr_uid &&
-	    td->td_ucred->cr_uid == p->p_ucred->cr_svuid &&
-	    td->td_ucred->cr_uid == p->p_ucred->cr_ruid);
-
 	/*
 	 * If p's gids aren't a subset, or the uids aren't a subset,
 	 * or the credential has changed, require appropriate privilege
 	 * for td to debug p.
 	 */
-	if (!grpsubset || !uidsubset) {
+	if (!cr_xids_subset(td->td_ucred, p->p_ucred)) {
 		error = priv_check(td, PRIV_DEBUG_DIFFCRED);
 		if (error)
 			return (error);
diff --git a/sys/sys/ucred.h b/sys/sys/ucred.h
index 7d04ea7de97f..ddd8f3ddb63d 100644
--- a/sys/sys/ucred.h
+++ b/sys/sys/ucred.h
@@ -237,6 +237,7 @@ void	cru2xt(struct thread *td, struct xucred *xcr);
 void	crsetgroups(struct ucred *cr, int ngrp, const gid_t *groups);
 void	crsetgroups_fallback(struct ucred *cr, int ngrp, const gid_t *groups,
 	    const gid_t fallback);
+bool	cr_xids_subset(struct ucred *active_cred, struct ucred *obj_cred);
 
 /*
  * Returns whether gid designates a primary group in cred.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202506092348.559Nm1tK088753>