git: 0d5b6fb6aee8 - main - kern_prot: extract code to check that active ids are superset of obj ids
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 09 Jun 2025 23:48:01 UTC
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.