git: f61c48f4403f - main - kern: rename crsetgroups_fallback, document it in ucred(9)
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 01 Aug 2025 00:50:57 UTC
The branch main has been updated by kevans:
URL: https://cgit.FreeBSD.org/src/commit/?id=f61c48f4403fc8c69f9b933d3f1bd9663008b0eb
commit f61c48f4403fc8c69f9b933d3f1bd9663008b0eb
Author: Kyle Evans <kevans@FreeBSD.org>
AuthorDate: 2025-08-01 00:50:48 +0000
Commit: Kyle Evans <kevans@FreeBSD.org>
CommitDate: 2025-08-01 00:50:48 +0000
kern: rename crsetgroups_fallback, document it in ucred(9)
As of FreeBSD 15.0, crsetgroups() *only* sets supplementary groups,
while crsetgroups_and_egid() will do both using an array of the same
style that previous versions used for crsetgroups() -- i.e., the first
element is the egid, and the remainder are supplementary groups.
Unlike the previous iteration of crsetgroups(), crsetgroups_and_egid()
is less prone to misuse as the caller must provide a default egid to use
in case the array is empty. This is particularly useful for groups
being set from data provided by userland.
Reviewed by: olce
Suggested by: olce
Differential Revision: https://reviews.freebsd.org/D51647
---
share/man/man9/ucred.9 | 19 +++++++++++++++++--
sys/fs/nfs/nfs_commonport.c | 2 +-
sys/fs/nfs/nfs_commonsubs.c | 2 +-
sys/fs/nfsserver/nfs_nfsdport.c | 2 +-
sys/fs/nfsserver/nfs_nfsdsocket.c | 2 +-
sys/kern/kern_prot.c | 10 +++++-----
sys/kern/vfs_export.c | 4 ++--
sys/rpc/rpcsec_gss/svc_rpcsec_gss.c | 2 +-
sys/rpc/svc_auth.c | 4 ++--
sys/sys/ucred.h | 4 ++--
10 files changed, 33 insertions(+), 18 deletions(-)
diff --git a/share/man/man9/ucred.9 b/share/man/man9/ucred.9
index 16de37dd8b35..38759bddb5b0 100644
--- a/share/man/man9/ucred.9
+++ b/share/man/man9/ucred.9
@@ -54,6 +54,9 @@
.Ft void
.Fn crsetgroups "struct ucred *cr" "int ngrp" "gid_t *groups"
.Ft void
+.Fn crsetgroups_and_egid "struct ucred *cr" "int ngrp" "gid_t *groups" \
+ "gid_t default_egid"
+.Ft void
.Fn cru2x "struct ucred *cr" "struct xucred *xcr"
.Sh DESCRIPTION
The
@@ -110,16 +113,28 @@ The actual copying is performed by
.Pp
The
.Fn crsetgroups
-function sets the
+and
+.Fn crsetgroups_and_egid
+functions set the
.Va cr_groups
and
.Va cr_ngroups
variables and allocates space as needed.
-It also truncates the group list to the current maximum number of
+They also truncate the group list to the current maximum number of
groups.
No other mechanism should be used to modify the
.Va cr_groups
array.
+Note that
+.Fn crsetgroups_and_egid
+will interpret the first element of
+.Va groups
+as the new effective GID and the rest of the array as the supplementary groups,
+and
+.Va default_egid
+will be used as the new effective GID only if
+.Va groups
+is empty.
.Pp
The
.Fn cru2x
diff --git a/sys/fs/nfs/nfs_commonport.c b/sys/fs/nfs/nfs_commonport.c
index e382b22fed74..e5fdb395c9f7 100644
--- a/sys/fs/nfs/nfs_commonport.c
+++ b/sys/fs/nfs/nfs_commonport.c
@@ -258,7 +258,7 @@ newnfs_copycred(struct nfscred *nfscr, struct ucred *cr)
KASSERT(nfscr->nfsc_ngroups >= 0,
("newnfs_copycred: negative nfsc_ngroups"));
cr->cr_uid = nfscr->nfsc_uid;
- crsetgroups_fallback(cr, nfscr->nfsc_ngroups, nfscr->nfsc_groups,
+ crsetgroups_and_egid(cr, nfscr->nfsc_ngroups, nfscr->nfsc_groups,
GID_NOGROUP);
}
diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c
index a957315aaa12..4ffc4ce5c29f 100644
--- a/sys/fs/nfs/nfs_commonsubs.c
+++ b/sys/fs/nfs/nfs_commonsubs.c
@@ -4143,7 +4143,7 @@ nfssvc_idname(struct nfsd_idargs *nidp)
*/
cr = crget();
cr->cr_uid = cr->cr_ruid = cr->cr_svuid = nidp->nid_uid;
- crsetgroups_fallback(cr, nidp->nid_ngroup, grps,
+ crsetgroups_and_egid(cr, nidp->nid_ngroup, grps,
GID_NOGROUP);
cr->cr_rgid = cr->cr_svgid = cr->cr_gid;
cr->cr_prison = curthread->td_ucred->cr_prison;
diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c
index 9e1a198bf34a..8c427c66c156 100644
--- a/sys/fs/nfsserver/nfs_nfsdport.c
+++ b/sys/fs/nfsserver/nfs_nfsdport.c
@@ -3466,7 +3466,7 @@ nfsd_excred(struct nfsrv_descript *nd, struct nfsexstuff *exp,
nd->nd_cred->cr_gid = credanon->cr_gid;
/*
* 'credanon' is already a 'struct ucred' that was built
- * internally with calls to crsetgroups_fallback(), so
+ * internally with calls to crsetgroups_and_egid(), so
* we don't need a fallback here.
*/
crsetgroups(nd->nd_cred, credanon->cr_ngroups,
diff --git a/sys/fs/nfsserver/nfs_nfsdsocket.c b/sys/fs/nfsserver/nfs_nfsdsocket.c
index d1b6198ba0e1..d6832b4f74be 100644
--- a/sys/fs/nfsserver/nfs_nfsdsocket.c
+++ b/sys/fs/nfsserver/nfs_nfsdsocket.c
@@ -1425,7 +1425,7 @@ nfsrv_createrootcred(void)
cr = crget();
cr->cr_uid = cr->cr_ruid = cr->cr_svuid = UID_ROOT;
- crsetgroups_fallback(cr, 0, NULL, GID_WHEEL);
+ crsetgroups_and_egid(cr, 0, NULL, GID_WHEEL);
cr->cr_rgid = cr->cr_svgid = cr->cr_gid;
cr->cr_prison = curthread->td_ucred->cr_prison;
prison_hold(cr->cr_prison);
diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c
index 632be229af5b..6bdef84a34c1 100644
--- a/sys/kern/kern_prot.c
+++ b/sys/kern/kern_prot.c
@@ -2928,19 +2928,19 @@ crsetgroups(struct ucred *cr, int ngrp, const gid_t *groups)
}
/*
- * Same as crsetgroups() but accepts an empty groups array.
+ * Same as crsetgroups() but sets the effective GID as well.
*
* This function ensures that an effective GID is always present in credentials.
- * An empty array will only set the effective GID to the fallback, while a
+ * An empty array will only set the effective GID to the default_egid, while a
* non-empty array will peel off groups[0] to set as the effective GID and use
* the remainder, if any, as supplementary groups.
*/
void
-crsetgroups_fallback(struct ucred *cr, int ngrp, const gid_t *groups,
- const gid_t fallback)
+crsetgroups_and_egid(struct ucred *cr, int ngrp, const gid_t *groups,
+ const gid_t default_egid)
{
if (ngrp == 0) {
- cr->cr_gid = fallback;
+ cr->cr_gid = default_egid;
cr->cr_ngroups = 0;
cr->cr_flags |= CRED_FLAG_GROUPSET;
return;
diff --git a/sys/kern/vfs_export.c b/sys/kern/vfs_export.c
index a314bda164de..bd7caa01e153 100644
--- a/sys/kern/vfs_export.c
+++ b/sys/kern/vfs_export.c
@@ -134,7 +134,7 @@ vfs_hang_addrlist(struct mount *mp, struct netexport *nep,
np->netc_exflags = argp->ex_flags;
np->netc_anon = crget();
np->netc_anon->cr_uid = argp->ex_uid;
- crsetgroups_fallback(np->netc_anon, argp->ex_ngroups,
+ crsetgroups_and_egid(np->netc_anon, argp->ex_ngroups,
argp->ex_groups, GID_NOGROUP);
np->netc_anon->cr_prison = &prison0;
prison_hold(np->netc_anon->cr_prison);
@@ -213,7 +213,7 @@ vfs_hang_addrlist(struct mount *mp, struct netexport *nep,
np->netc_exflags = argp->ex_flags;
np->netc_anon = crget();
np->netc_anon->cr_uid = argp->ex_uid;
- crsetgroups_fallback(np->netc_anon, argp->ex_ngroups, argp->ex_groups,
+ crsetgroups_and_egid(np->netc_anon, argp->ex_ngroups, argp->ex_groups,
GID_NOGROUP);
np->netc_anon->cr_prison = &prison0;
prison_hold(np->netc_anon->cr_prison);
diff --git a/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c b/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c
index b1790dd167d5..51077c71822c 100644
--- a/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c
+++ b/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c
@@ -537,7 +537,7 @@ rpc_gss_svc_getcred(struct svc_req *req, struct ucred **crp, int *flavorp)
cr = client->cl_cred = crget();
cr->cr_uid = cr->cr_ruid = cr->cr_svuid = uc->uid;
cr->cr_rgid = cr->cr_svgid = uc->gid;
- crsetgroups_fallback(cr, uc->gidlen, uc->gidlist, uc->gid);
+ crsetgroups_and_egid(cr, uc->gidlen, uc->gidlist, uc->gid);
cr->cr_prison = curthread->td_ucred->cr_prison;
prison_hold(cr->cr_prison);
*crp = crhold(cr);
diff --git a/sys/rpc/svc_auth.c b/sys/rpc/svc_auth.c
index 838fa9ed313a..acbb1112e270 100644
--- a/sys/rpc/svc_auth.c
+++ b/sys/rpc/svc_auth.c
@@ -192,7 +192,7 @@ svc_getcred(struct svc_req *rqst, struct ucred **crp, int *flavorp)
return (FALSE);
cr = crget();
cr->cr_uid = cr->cr_ruid = cr->cr_svuid = xprt->xp_uid;
- crsetgroups_fallback(cr, xprt->xp_ngrps, xprt->xp_gidp, GID_NOGROUP);
+ crsetgroups_and_egid(cr, xprt->xp_ngrps, xprt->xp_gidp, GID_NOGROUP);
cr->cr_rgid = cr->cr_svgid = cr->cr_gid;
cr->cr_prison = curthread->td_ucred->cr_prison;
prison_hold(cr->cr_prison);
@@ -207,7 +207,7 @@ svc_getcred(struct svc_req *rqst, struct ucred **crp, int *flavorp)
return (FALSE);
cr = crget();
cr->cr_uid = cr->cr_ruid = cr->cr_svuid = xcr->cr_uid;
- crsetgroups_fallback(cr, xcr->cr_ngroups, xcr->cr_groups, GID_NOGROUP);
+ crsetgroups_and_egid(cr, xcr->cr_ngroups, xcr->cr_groups, GID_NOGROUP);
cr->cr_rgid = cr->cr_svgid = cr->cr_gid;
cr->cr_prison = curthread->td_ucred->cr_prison;
prison_hold(cr->cr_prison);
diff --git a/sys/sys/ucred.h b/sys/sys/ucred.h
index cd4efcb71c0d..9c1d8545af34 100644
--- a/sys/sys/ucred.h
+++ b/sys/sys/ucred.h
@@ -242,8 +242,8 @@ void crcowfree(struct thread *td);
void cru2x(struct ucred *cr, struct xucred *xcr);
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);
+void crsetgroups_and_egid(struct ucred *cr, int ngrp, const gid_t *groups,
+ const gid_t default_egid);
bool cr_xids_subset(struct ucred *active_cred, struct ucred *obj_cred);
/*