The branch main has been updated by kevans:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=46c07316f90628a82dd461376ccff64a81254325

commit 46c07316f90628a82dd461376ccff64a81254325
Author:     Kyle Evans <kev...@freebsd.org>
AuthorDate: 2025-07-24 14:59:08 +0000
Commit:     Kyle Evans <kev...@freebsd.org>
CommitDate: 2025-07-24 14:59:08 +0000

    kern: adopt the cr_gid macro for cr_groups[0] more widely
    
    A future change may split cr_gid out of cr_groups[0] so that there's a
    cleaner separation between the supplemental groups and the effective
    group.  Do the mechanical conversion where we can, and drop some
    comments where we need further work because some assumptions about
    cr_gid == cr_groups[0] have been made.
    
    This should not be a functional change, but downstreams and other
    out-of-tree code are advised to investigate their usage of cr_groups
    sooner rather than later, as a future change will render assumptions
    about these two being equivalent harmful.
    
    Reviewed by:    asomers, kib, olce
    Differential Revision:  https://reviews.freebsd.org/D51153
---
 sys/fs/fuse/fuse_internal.h     |  6 +++---
 sys/fs/fuse/fuse_ipc.c          |  2 +-
 sys/fs/fuse/fuse_vnops.c        |  2 +-
 sys/fs/nfs/nfs_commonport.c     |  3 ++-
 sys/fs/nfsclient/nfs_clrpcops.c |  3 ++-
 sys/kern/kern_prot.c            | 38 +++++++++++++++++++-------------------
 sys/kern/vfs_syscalls.c         |  4 ++--
 sys/netpfil/pf/pf.c             |  4 ++--
 sys/netsmb/smb_conn.c           |  4 ++--
 sys/rpc/authunix_prot.c         |  7 ++++---
 sys/rpc/svc_auth_unix.c         |  3 ++-
 sys/security/audit/audit.c      |  2 +-
 sys/security/audit/audit_arg.c  |  2 +-
 sys/ufs/ufs/ufs_vnops.c         | 12 ++++++++++--
 14 files changed, 52 insertions(+), 40 deletions(-)

diff --git a/sys/fs/fuse/fuse_internal.h b/sys/fs/fuse/fuse_internal.h
index cddf88095840..932012b5f52a 100644
--- a/sys/fs/fuse/fuse_internal.h
+++ b/sys/fs/fuse/fuse_internal.h
@@ -208,9 +208,9 @@ fuse_match_cred(struct ucred *basecred, struct ucred 
*usercred)
        if (basecred->cr_uid == usercred->cr_uid             &&
            basecred->cr_uid == usercred->cr_ruid            &&
            basecred->cr_uid == usercred->cr_svuid           &&
-           basecred->cr_groups[0] == usercred->cr_groups[0] &&
-           basecred->cr_groups[0] == usercred->cr_rgid      &&
-           basecred->cr_groups[0] == usercred->cr_svgid)
+           basecred->cr_gid == usercred->cr_gid             &&
+           basecred->cr_gid == usercred->cr_rgid            &&
+           basecred->cr_gid == usercred->cr_svgid)
                return (0);
 
        return (EPERM);
diff --git a/sys/fs/fuse/fuse_ipc.c b/sys/fs/fuse/fuse_ipc.c
index 0b6048644d32..a751c09159ff 100644
--- a/sys/fs/fuse/fuse_ipc.c
+++ b/sys/fs/fuse/fuse_ipc.c
@@ -868,7 +868,7 @@ fuse_setup_ihead(struct fuse_in_header *ihead, struct 
fuse_ticket *ftick,
 
        ihead->pid = pid;
        ihead->uid = cred->cr_uid;
-       ihead->gid = cred->cr_groups[0];
+       ihead->gid = cred->cr_gid;
 }
 
 /*
diff --git a/sys/fs/fuse/fuse_vnops.c b/sys/fs/fuse/fuse_vnops.c
index ae28617537fd..32872e8f3f3a 100644
--- a/sys/fs/fuse/fuse_vnops.c
+++ b/sys/fs/fuse/fuse_vnops.c
@@ -884,7 +884,7 @@ fuse_vnop_copy_file_range(struct vop_copy_file_range_args 
*ap)
                return (EXTERROR(ENOSYS, "FUSE_COPY_FILE_RANGE does not "
                    "support different credentials for infd and outfd"));
 
-       if (incred->cr_groups[0] != outcred->cr_groups[0])
+       if (incred->cr_gid != outcred->cr_gid)
                return (EXTERROR(ENOSYS, "FUSE_COPY_FILE_RANGE does not "
                    "support different credentials for infd and outfd"));
 
diff --git a/sys/fs/nfs/nfs_commonport.c b/sys/fs/nfs/nfs_commonport.c
index 0c94f4e7dc52..222cfc03e4b3 100644
--- a/sys/fs/nfs/nfs_commonport.c
+++ b/sys/fs/nfs/nfs_commonport.c
@@ -379,7 +379,8 @@ newnfs_setroot(struct ucred *cred)
 {
 
        cred->cr_uid = 0;
-       cred->cr_groups[0] = 0;
+       cred->cr_gid = 0;
+       /* XXXKE Fix this if cr_gid gets separated out. */
        cred->cr_ngroups = 1;
 }
 
diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c
index 2f3c59b68518..36b534be531e 100644
--- a/sys/fs/nfsclient/nfs_clrpcops.c
+++ b/sys/fs/nfsclient/nfs_clrpcops.c
@@ -6933,7 +6933,8 @@ nfscl_dofflayoutio(vnode_t vp, struct uio *uiop, int 
*iomode, int *must_commit,
                if ((dp->nfsdi_flags & NFSDI_TIGHTCOUPLED) == 0) {
                        tcred = NFSNEWCRED(cred);
                        tcred->cr_uid = flp->nfsfl_ffm[mirror].user;
-                       tcred->cr_groups[0] = flp->nfsfl_ffm[mirror].group;
+                       tcred->cr_gid = flp->nfsfl_ffm[mirror].group;
+                       /* XXXKE Fix this if cr_gid gets separated out. */
                        tcred->cr_ngroups = 1;
                } else
                        tcred = cred;
diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c
index d9aeec68e620..0f0bc056cafd 100644
--- a/sys/kern/kern_prot.c
+++ b/sys/kern/kern_prot.c
@@ -287,7 +287,7 @@ sys_getgid(struct thread *td, struct getgid_args *uap)
 
        td->td_retval[0] = td->td_ucred->cr_rgid;
 #if defined(COMPAT_43)
-       td->td_retval[1] = td->td_ucred->cr_groups[0];
+       td->td_retval[1] = td->td_ucred->cr_gid;
 #endif
        return (0);
 }
@@ -307,7 +307,7 @@ int
 sys_getegid(struct thread *td, struct getegid_args *uap)
 {
 
-       td->td_retval[0] = td->td_ucred->cr_groups[0];
+       td->td_retval[0] = td->td_ucred->cr_gid;
        return (0);
 }
 
@@ -1080,7 +1080,7 @@ sys_setgid(struct thread *td, struct setgid_args *uap)
            gid != oldcred->cr_svgid &&         /* allow setgid(saved gid) */
 #endif
 #ifdef POSIX_APPENDIX_B_4_2_2  /* Use BSD-compat clause from B.4.2.2 */
-           gid != oldcred->cr_groups[0] && /* allow setgid(getegid()) */
+           gid != oldcred->cr_gid && /* allow setgid(getegid()) */
 #endif
            (error = priv_check_cred(oldcred, PRIV_CRED_SETGID)) != 0)
                goto fail;
@@ -1092,7 +1092,7 @@ sys_setgid(struct thread *td, struct setgid_args *uap)
         */
        if (
 #ifdef POSIX_APPENDIX_B_4_2_2  /* use the clause from B.4.2.2 */
-           gid == oldcred->cr_groups[0] ||
+           gid == oldcred->cr_gid ||
 #endif
            /* We are using privs. */
            priv_check_cred(oldcred, PRIV_CRED_SETGID) == 0)
@@ -1121,7 +1121,7 @@ sys_setgid(struct thread *td, struct setgid_args *uap)
         * In all cases permitted cases, we are changing the egid.
         * Copy credentials so other references do not see our changes.
         */
-       if (oldcred->cr_groups[0] != gid) {
+       if (oldcred->cr_gid != gid) {
                change_egid(newcred, gid);
                setsugid(p);
        }
@@ -1167,7 +1167,7 @@ sys_setegid(struct thread *td, struct setegid_args *uap)
            (error = priv_check_cred(oldcred, PRIV_CRED_SETEGID)) != 0)
                goto fail;
 
-       if (oldcred->cr_groups[0] != egid) {
+       if (oldcred->cr_gid != egid) {
                change_egid(newcred, egid);
                setsugid(p);
        }
@@ -1393,12 +1393,12 @@ sys_setregid(struct thread *td, struct setregid_args 
*uap)
 
        if (((rgid != (gid_t)-1 && rgid != oldcred->cr_rgid &&
            rgid != oldcred->cr_svgid) ||
-            (egid != (gid_t)-1 && egid != oldcred->cr_groups[0] &&
+            (egid != (gid_t)-1 && egid != oldcred->cr_gid &&
             egid != oldcred->cr_rgid && egid != oldcred->cr_svgid)) &&
            (error = priv_check_cred(oldcred, PRIV_CRED_SETREGID)) != 0)
                goto fail;
 
-       if (egid != (gid_t)-1 && oldcred->cr_groups[0] != egid) {
+       if (egid != (gid_t)-1 && oldcred->cr_gid != egid) {
                change_egid(newcred, egid);
                setsugid(p);
        }
@@ -1406,9 +1406,9 @@ sys_setregid(struct thread *td, struct setregid_args *uap)
                change_rgid(newcred, rgid);
                setsugid(p);
        }
-       if ((rgid != (gid_t)-1 || newcred->cr_groups[0] != newcred->cr_rgid) &&
-           newcred->cr_svgid != newcred->cr_groups[0]) {
-               change_svgid(newcred, newcred->cr_groups[0]);
+       if ((rgid != (gid_t)-1 || newcred->cr_gid != newcred->cr_rgid) &&
+           newcred->cr_svgid != newcred->cr_gid) {
+               change_svgid(newcred, newcred->cr_gid);
                setsugid(p);
        }
        proc_set_cred(p, newcred);
@@ -1547,17 +1547,17 @@ sys_setresgid(struct thread *td, struct setresgid_args 
*uap)
 
        if (((rgid != (gid_t)-1 && rgid != oldcred->cr_rgid &&
              rgid != oldcred->cr_svgid &&
-             rgid != oldcred->cr_groups[0]) ||
+             rgid != oldcred->cr_gid) ||
             (egid != (gid_t)-1 && egid != oldcred->cr_rgid &&
              egid != oldcred->cr_svgid &&
-             egid != oldcred->cr_groups[0]) ||
+             egid != oldcred->cr_gid) ||
             (sgid != (gid_t)-1 && sgid != oldcred->cr_rgid &&
              sgid != oldcred->cr_svgid &&
-             sgid != oldcred->cr_groups[0])) &&
+             sgid != oldcred->cr_gid)) &&
            (error = priv_check_cred(oldcred, PRIV_CRED_SETRESGID)) != 0)
                goto fail;
 
-       if (egid != (gid_t)-1 && oldcred->cr_groups[0] != egid) {
+       if (egid != (gid_t)-1 && oldcred->cr_gid != egid) {
                change_egid(newcred, egid);
                setsugid(p);
        }
@@ -1626,8 +1626,8 @@ sys_getresgid(struct thread *td, struct getresgid_args 
*uap)
                error1 = copyout(&cred->cr_rgid,
                    uap->rgid, sizeof(cred->cr_rgid));
        if (uap->egid)
-               error2 = copyout(&cred->cr_groups[0],
-                   uap->egid, sizeof(cred->cr_groups[0]));
+               error2 = copyout(&cred->cr_gid,
+                   uap->egid, sizeof(cred->cr_gid));
        if (uap->sgid)
                error3 = copyout(&cred->cr_svgid,
                    uap->sgid, sizeof(cred->cr_svgid));
@@ -1737,7 +1737,7 @@ groupmember(gid_t gid, const struct ucred *cred)
 
        groups_check_positive_len(cred->cr_ngroups);
 
-       if (gid == cred->cr_groups[0])
+       if (gid == cred->cr_gid)
                return (true);
 
        return (group_is_supplementary(gid, cred));
@@ -3015,7 +3015,7 @@ void
 change_egid(struct ucred *newcred, gid_t egid)
 {
 
-       newcred->cr_groups[0] = egid;
+       newcred->cr_gid = egid;
 }
 
 /*-
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index c71e0d9ee569..25d40a9806cb 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -2253,10 +2253,10 @@ kern_accessat(struct thread *td, int fd, const char 
*path,
        cred = td->td_ucred;
        if ((flag & AT_EACCESS) == 0 &&
            ((cred->cr_uid != cred->cr_ruid ||
-           cred->cr_rgid != cred->cr_groups[0]))) {
+           cred->cr_rgid != cred->cr_gid))) {
                usecred = crdup(cred);
                usecred->cr_uid = cred->cr_ruid;
-               usecred->cr_groups[0] = cred->cr_rgid;
+               usecred->cr_gid = cred->cr_rgid;
                td->td_ucred = usecred;
        } else
                usecred = cred;
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
index c669be47b063..41e9ca27912d 100644
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -4976,7 +4976,7 @@ pf_socket_lookup(struct pf_pdesc *pd)
        }
        INP_RLOCK_ASSERT(inp);
        pd->lookup.uid = inp->inp_cred->cr_uid;
-       pd->lookup.gid = inp->inp_cred->cr_groups[0];
+       pd->lookup.gid = inp->inp_cred->cr_gid;
        INP_RUNLOCK(inp);
 
        return (1);
@@ -5760,7 +5760,7 @@ pf_test_rule(struct pf_krule **rm, struct pf_kstate **sm,
        if (inp != NULL) {
                INP_LOCK_ASSERT(inp);
                pd->lookup.uid = inp->inp_cred->cr_uid;
-               pd->lookup.gid = inp->inp_cred->cr_groups[0];
+               pd->lookup.gid = inp->inp_cred->cr_gid;
                pd->lookup.done = 1;
        }
 
diff --git a/sys/netsmb/smb_conn.c b/sys/netsmb/smb_conn.c
index 259635e2d8d5..ab6cd130a057 100644
--- a/sys/netsmb/smb_conn.c
+++ b/sys/netsmb/smb_conn.c
@@ -422,7 +422,7 @@ smb_vc_create(struct smb_vcspec *vcspec,
        if (uid == SMBM_ANY_OWNER)
                uid = realuid;
        if (gid == SMBM_ANY_GROUP)
-               gid = cred->cr_groups[0];
+               gid = cred->cr_gid;
        vcp->vc_uid = uid;
        vcp->vc_grp = gid;
 
@@ -765,7 +765,7 @@ smb_share_create(struct smb_vc *vcp, struct smb_sharespec 
*shspec,
        if (uid == SMBM_ANY_OWNER)
                uid = realuid;
        if (gid == SMBM_ANY_GROUP)
-               gid = cred->cr_groups[0];
+               gid = cred->cr_gid;
        ssp = smb_zmalloc(sizeof(*ssp), M_SMBCONN, M_WAITOK);
        smb_co_init(SSTOCP(ssp), SMBL_SHARE, "smbss ilock", "smbss");
        ssp->obj.co_free = smb_share_free;
diff --git a/sys/rpc/authunix_prot.c b/sys/rpc/authunix_prot.c
index 91fb96f44397..7b531946488a 100644
--- a/sys/rpc/authunix_prot.c
+++ b/sys/rpc/authunix_prot.c
@@ -93,9 +93,10 @@ xdr_authunix_parms(XDR *xdrs, uint32_t *time, struct xucred 
*cred)
 
        if (!xdr_uint32_t(xdrs, &cred->cr_uid))
                return (FALSE);
-       if (!xdr_uint32_t(xdrs, &cred->cr_groups[0]))
+       if (!xdr_uint32_t(xdrs, &cred->cr_gid))
                return (FALSE);
 
+       /* XXXKE Fix this is cr_gid gets separated out. */
        if (xdrs->x_op == XDR_ENCODE) {
                ngroups = cred->cr_ngroups - 1;
                if (ngroups > NGRPS)
@@ -105,7 +106,7 @@ xdr_authunix_parms(XDR *xdrs, uint32_t *time, struct xucred 
*cred)
        if (!xdr_uint32_t(xdrs, &ngroups))
                return (FALSE);
        for (i = 0; i < ngroups; i++) {
-               if (i + 1 < ngroups_max + 1) {
+               if (i < ngroups_max) {
                        if (!xdr_uint32_t(xdrs, &cred->cr_groups[i + 1]))
                                return (FALSE);
                } else {
@@ -115,7 +116,7 @@ xdr_authunix_parms(XDR *xdrs, uint32_t *time, struct xucred 
*cred)
        }
 
        if (xdrs->x_op == XDR_DECODE) {
-               if (ngroups + 1 > ngroups_max + 1)
+               if (ngroups > ngroups_max)
                        cred->cr_ngroups = ngroups_max + 1;
                else
                        cred->cr_ngroups = ngroups + 1;
diff --git a/sys/rpc/svc_auth_unix.c b/sys/rpc/svc_auth_unix.c
index 5d6402a05006..b10ef33be704 100644
--- a/sys/rpc/svc_auth_unix.c
+++ b/sys/rpc/svc_auth_unix.c
@@ -83,12 +83,13 @@ _svcauth_unix(struct svc_req *rqst, struct rpc_msg *msg)
                str_len = RNDUP(str_len);
                buf += str_len / sizeof (int32_t);
                xcr->cr_uid = IXDR_GET_UINT32(buf);
-               xcr->cr_groups[0] = IXDR_GET_UINT32(buf);
+               xcr->cr_gid = IXDR_GET_UINT32(buf);
                gid_len = (size_t)IXDR_GET_UINT32(buf);
                if (gid_len > NGRPS) {
                        stat = AUTH_BADCRED;
                        goto done;
                }
+               /* XXXKE Fix this if cr_gid gets separated out. */
                for (i = 0; i < gid_len; i++) {
                        if (i + 1 < XU_NGROUPS)
                                xcr->cr_groups[i + 1] = IXDR_GET_INT32(buf);
diff --git a/sys/security/audit/audit.c b/sys/security/audit/audit.c
index 05928f1c33e8..7ec50d990d4e 100644
--- a/sys/security/audit/audit.c
+++ b/sys/security/audit/audit.c
@@ -279,7 +279,7 @@ audit_record_ctor(void *mem, int size, void *arg, int flags)
        cru2x(cred, &ar->k_ar.ar_subj_cred);
        ar->k_ar.ar_subj_ruid = cred->cr_ruid;
        ar->k_ar.ar_subj_rgid = cred->cr_rgid;
-       ar->k_ar.ar_subj_egid = cred->cr_groups[0];
+       ar->k_ar.ar_subj_egid = cred->cr_gid;
        ar->k_ar.ar_subj_auid = cred->cr_audit.ai_auid;
        ar->k_ar.ar_subj_asid = cred->cr_audit.ai_asid;
        ar->k_ar.ar_subj_pid = td->td_proc->p_pid;
diff --git a/sys/security/audit/audit_arg.c b/sys/security/audit/audit_arg.c
index c667d3968817..3ea645373dbe 100644
--- a/sys/security/audit/audit_arg.c
+++ b/sys/security/audit/audit_arg.c
@@ -408,7 +408,7 @@ audit_arg_process(struct proc *p)
        cred = p->p_ucred;
        ar->k_ar.ar_arg_auid = cred->cr_audit.ai_auid;
        ar->k_ar.ar_arg_euid = cred->cr_uid;
-       ar->k_ar.ar_arg_egid = cred->cr_groups[0];
+       ar->k_ar.ar_arg_egid = cred->cr_gid;
        ar->k_ar.ar_arg_ruid = cred->cr_ruid;
        ar->k_ar.ar_arg_rgid = cred->cr_rgid;
        ar->k_ar.ar_arg_asid = cred->cr_audit.ai_asid;
diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c
index 53fac4b0665e..17308706c3f4 100644
--- a/sys/ufs/ufs/ufs_vnops.c
+++ b/sys/ufs/ufs/ufs_vnops.c
@@ -2064,9 +2064,13 @@ ufs_mkdir(
                                 */
                                ucred.cr_ref = 1;
                                ucred.cr_uid = ip->i_uid;
+
+                               /*
+                                * XXXKE Fix this is cr_gid gets separated out
+                                */
                                ucred.cr_ngroups = 1;
                                ucred.cr_groups = &ucred_group;
-                               ucred.cr_groups[0] = dp->i_gid;
+                               ucred.cr_gid = ucred_group = dp->i_gid;
                                ucp = &ucred;
                        }
 #endif
@@ -2823,9 +2827,13 @@ ufs_makeinode(int mode, struct vnode *dvp, struct vnode 
**vpp,
                         */
                        ucred.cr_ref = 1;
                        ucred.cr_uid = ip->i_uid;
+
+                       /*
+                        * XXXKE Fix this is cr_gid gets separated out
+                        */
                        ucred.cr_ngroups = 1;
                        ucred.cr_groups = &ucred_group;
-                       ucred.cr_groups[0] = pdir->i_gid;
+                       ucred.cr_gid = ucred_group = pdir->i_gid;
                        ucp = &ucred;
 #endif
                } else {

Reply via email to