commit 56027d1824b9f0655872f824bbd1640fb2284d77 Author: Kyle Evans Date: Thu Jul 3 13:50:48 2025 -0500 RFC: kern: start tracking cr_gid outside of cr_groups[] This is the (mostly) kernel side of de-conflating cr_gid and the supplemental groups. The pre-existing behavior for getgroups() and setgroups() is retained to keep the user <-> kernel boundary functionally the same while we audit use of these syscalls, but we can remove a lot of the internal special-casing just by reorganizing ucred like this. struct xucred has been altered because the cr_gid macro becomes problematic if ucred has a real cr_gid member but xucred does not. Most notably, they both also have cr_groups[] members, so the definition means that we could easily have situations where we end up using the first supplemental group as the egid in some places. diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c index b88f1451f1a2..766db59c3b00 100644 --- a/sys/compat/linux/linux_misc.c +++ b/sys/compat/linux/linux_misc.c @@ -1035,25 +1035,19 @@ linux_setgroups(struct thread *td, struct linux_setgroups_args *args) struct proc *p; ngrp = args->gidsetsize; - if (ngrp < 0 || ngrp >= ngroups_max + 1) + if (ngrp < 0 || ngrp >= ngroups_max) return (EINVAL); linux_gidset = malloc(ngrp * sizeof(*linux_gidset), M_LINUX, M_WAITOK); error = copyin(args->grouplist, linux_gidset, ngrp * sizeof(l_gid_t)); if (error) goto out; newcred = crget(); - crextend(newcred, ngrp + 1); + crextend(newcred, ngrp); p = td->td_proc; PROC_LOCK(p); oldcred = p->p_ucred; crcopy(newcred, oldcred); - /* - * cr_groups[0] holds egid. Setting the whole set from - * the supplied set will cause egid to be changed too. - * Keep cr_groups[0] unchanged to prevent that. - */ - if ((error = priv_check_cred(oldcred, PRIV_CRED_SETGROUPS)) != 0) { PROC_UNLOCK(p); crfree(newcred); @@ -1061,16 +1055,16 @@ linux_setgroups(struct thread *td, struct linux_setgroups_args *args) } if (ngrp > 0) { - newcred->cr_ngroups = ngrp + 1; + newcred->cr_ngroups = ngrp; bsd_gidset = newcred->cr_groups; ngrp--; while (ngrp >= 0) { - bsd_gidset[ngrp + 1] = linux_gidset[ngrp]; + bsd_gidset[ngrp] = linux_gidset[ngrp]; ngrp--; } } else - newcred->cr_ngroups = 1; + newcred->cr_ngroups = 0; setsugid(p); proc_set_cred(p, newcred); @@ -1092,13 +1086,7 @@ linux_getgroups(struct thread *td, struct linux_getgroups_args *args) cred = td->td_ucred; bsd_gidset = cred->cr_groups; - bsd_gidsetsz = cred->cr_ngroups - 1; - - /* - * cr_groups[0] holds egid. Returning the whole set - * here will cause a duplicate. Exclude cr_groups[0] - * to prevent that. - */ + bsd_gidsetsz = cred->cr_ngroups; if ((ngrp = args->gidsetsize) == 0) { td->td_retval[0] = bsd_gidsetsz; @@ -1112,7 +1100,7 @@ linux_getgroups(struct thread *td, struct linux_getgroups_args *args) linux_gidset = malloc(bsd_gidsetsz * sizeof(*linux_gidset), M_LINUX, M_WAITOK); while (ngrp < bsd_gidsetsz) { - linux_gidset[ngrp] = bsd_gidset[ngrp + 1]; + linux_gidset[ngrp] = bsd_gidset[ngrp]; ngrp++; } diff --git a/sys/compat/linux/linux_uid16.c b/sys/compat/linux/linux_uid16.c index a0c9f1c39198..9d71b5e96ee4 100644 --- a/sys/compat/linux/linux_uid16.c +++ b/sys/compat/linux/linux_uid16.c @@ -92,7 +92,7 @@ linux_setgroups16(struct thread *td, struct linux_setgroups16_args *args) struct proc *p; ngrp = args->gidsetsize; - if (ngrp < 0 || ngrp >= ngroups_max + 1) + if (ngrp < 0 || ngrp >= ngroups_max) return (EINVAL); linux_gidset = malloc(ngrp * sizeof(*linux_gidset), M_LINUX, M_WAITOK); error = copyin(args->gidset, linux_gidset, ngrp * sizeof(l_gid16_t)); @@ -106,12 +106,6 @@ linux_setgroups16(struct thread *td, struct linux_setgroups16_args *args) PROC_LOCK(p); oldcred = crcopysafe(p, newcred); - /* - * cr_groups[0] holds egid. Setting the whole set from - * the supplied set will cause egid to be changed too. - * Keep cr_groups[0] unchanged to prevent that. - */ - if ((error = priv_check_cred(oldcred, PRIV_CRED_SETGROUPS)) != 0) { PROC_UNLOCK(p); crfree(newcred); @@ -122,17 +116,17 @@ linux_setgroups16(struct thread *td, struct linux_setgroups16_args *args) } if (ngrp > 0) { - newcred->cr_ngroups = ngrp + 1; + newcred->cr_ngroups = ngrp; bsd_gidset = newcred->cr_groups; ngrp--; while (ngrp >= 0) { - bsd_gidset[ngrp + 1] = linux_gidset[ngrp]; + bsd_gidset[ngrp] = linux_gidset[ngrp]; ngrp--; } } else - newcred->cr_ngroups = 1; + newcred->cr_ngroups = 0; setsugid(td->td_proc); proc_set_cred(p, newcred); @@ -155,13 +149,7 @@ linux_getgroups16(struct thread *td, struct linux_getgroups16_args *args) cred = td->td_ucred; bsd_gidset = cred->cr_groups; - bsd_gidsetsz = cred->cr_ngroups - 1; - - /* - * cr_groups[0] holds egid. Returning the whole set - * here will cause a duplicate. Exclude cr_groups[0] - * to prevent that. - */ + bsd_gidsetsz = cred->cr_ngroups; if ((ngrp = args->gidsetsize) == 0) { td->td_retval[0] = bsd_gidsetsz; @@ -175,7 +163,7 @@ linux_getgroups16(struct thread *td, struct linux_getgroups16_args *args) linux_gidset = malloc(bsd_gidsetsz * sizeof(*linux_gidset), M_LINUX, M_WAITOK); while (ngrp < bsd_gidsetsz) { - linux_gidset[ngrp] = bsd_gidset[ngrp + 1]; + linux_gidset[ngrp] = bsd_gidset[ngrp]; ngrp++; } diff --git a/sys/fs/nfs/nfs_commonport.c b/sys/fs/nfs/nfs_commonport.c index 222cfc03e4b3..e382b22fed74 100644 --- a/sys/fs/nfs/nfs_commonport.c +++ b/sys/fs/nfs/nfs_commonport.c @@ -380,8 +380,7 @@ newnfs_setroot(struct ucred *cred) cred->cr_uid = 0; cred->cr_gid = 0; - /* XXXKE Fix this if cr_gid gets separated out. */ - cred->cr_ngroups = 1; + cred->cr_ngroups = 0; } /* diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c index f93455aef1a0..a3998e05d08b 100644 --- a/sys/fs/nfsclient/nfs_clrpcops.c +++ b/sys/fs/nfsclient/nfs_clrpcops.c @@ -6926,8 +6926,7 @@ nfscl_dofflayoutio(vnode_t vp, struct uio *uiop, int *iomode, int *must_commit, tcred = NFSNEWCRED(cred); tcred->cr_uid = flp->nfsfl_ffm[mirror].user; tcred->cr_gid = flp->nfsfl_ffm[mirror].group; - /* XXXKE Fix this if cr_gid gets separated out. */ - tcred->cr_ngroups = 1; + tcred->cr_ngroups = 0; } else tcred = cred; if (rwflag == NFSV4OPEN_ACCESSREAD) diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c index 0f0bc056cafd..7a452e17b21f 100644 --- a/sys/kern/kern_prot.c +++ b/sys/kern/kern_prot.c @@ -99,12 +99,11 @@ static inline void groups_check_positive_len(int ngrp) { MPASS2(ngrp >= 0, "negative number of groups"); - MPASS2(ngrp != 0, "at least one group expected (effective GID)"); } static inline void groups_check_max_len(int ngrp) { - MPASS2(ngrp <= ngroups_max + 1, "too many groups"); + MPASS2(ngrp <= ngroups_max, "too many groups"); } static void groups_normalize(int *ngrp, gid_t *groups); @@ -321,10 +320,17 @@ int sys_getgroups(struct thread *td, struct getgroups_args *uap) { struct ucred *cred; + gid_t *ugidset; int ngrp, error; cred = td->td_ucred; - ngrp = cred->cr_ngroups; + + /* + * cr_gid has been moved out of cr_groups, but we'll continue exporting + * the egid as groups[0] for the time being until we audit userland for + * any surprises. + */ + ngrp = cred->cr_ngroups + 1; if (uap->gidsetsize == 0) { error = 0; @@ -333,7 +339,17 @@ sys_getgroups(struct thread *td, struct getgroups_args *uap) if (uap->gidsetsize < ngrp) return (EINVAL); - error = copyout(cred->cr_groups, uap->gidset, ngrp * sizeof(gid_t)); + ugidset = uap->gidset; + error = copyout(&cred->cr_gid, ugidset, sizeof(*ugidset)); + if (error != 0) + goto out; + + if (ngrp > 1) { + ugidset++; + + error = copyout(cred->cr_groups, ugidset, + (ngrp - 1) * sizeof(*ugidset)); + } out: td->td_retval[0] = ngrp; return (error); @@ -526,14 +542,14 @@ kern_setcred_copyin_supp_groups(struct setcred *const wcred, * supplementary groups. */ *groups = wcred->sc_supp_groups_nb < CRED_SMALLGROUPS_NB ? - smallgroups : malloc((wcred->sc_supp_groups_nb + 1) * + smallgroups : malloc(wcred->sc_supp_groups_nb * sizeof(*groups), M_TEMP, M_WAITOK); - error = copyin(wcred->sc_supp_groups, *groups + 1, + error = copyin(wcred->sc_supp_groups, *groups, wcred->sc_supp_groups_nb * sizeof(*groups)); if (error != 0) return (error); - wcred->sc_supp_groups = *groups + 1; + wcred->sc_supp_groups = *groups; } else { wcred->sc_supp_groups_nb = 0; wcred->sc_supp_groups = NULL; @@ -652,7 +668,7 @@ sys_setcred(struct thread *td, struct setcred_args *uap) * CAUTION: This function normalizes groups in 'wcred'. * * If 'preallocated_groups' is non-NULL, it must be an already allocated array - * of size 'wcred->sc_supp_groups_nb + 1', with the supplementary groups + * of size 'wcred->sc_supp_groups_nb', with the supplementary groups * starting at index 1, and 'wcred->sc_supp_groups' then must point to the first * supplementary group. */ @@ -689,9 +705,9 @@ kern_setcred(struct thread *const td, const u_int flags, } else { groups = wcred->sc_supp_groups_nb < CRED_SMALLGROUPS_NB ? smallgroups : - malloc((wcred->sc_supp_groups_nb + 1) * + malloc(wcred->sc_supp_groups_nb * sizeof(*groups), M_TEMP, M_WAITOK); - memcpy(groups + 1, wcred->sc_supp_groups, + memcpy(groups, wcred->sc_supp_groups, wcred->sc_supp_groups_nb * sizeof(*groups)); } } @@ -732,10 +748,8 @@ kern_setcred(struct thread *const td, const u_int flags, * Output the raw supplementary groups array for better * traceability. */ - AUDIT_ARG_GROUPSET(groups + 1, ngrp); - ++ngrp; + AUDIT_ARG_GROUPSET(groups, ngrp); groups_normalize(&ngrp, groups); - wcred->sc_supp_groups_nb = ngrp - 1; } /* @@ -746,7 +760,7 @@ kern_setcred(struct thread *const td, const u_int flags, new_cred = crget(); to_free_cred = new_cred; if (flags & SETCREDF_SUPP_GROUPS) - crextend(new_cred, wcred->sc_supp_groups_nb + 1); + crextend(new_cred, wcred->sc_supp_groups_nb); #ifdef MAC mac_cred_setcred_enter(); @@ -778,9 +792,7 @@ kern_setcred(struct thread *const td, const u_int flags, * ones. */ if (flags & SETCREDF_SUPP_GROUPS) { - groups[0] = flags & SETCREDF_GID ? wcred->sc_gid : - new_cred->cr_gid; - crsetgroups_internal(new_cred, wcred->sc_supp_groups_nb + 1, + crsetgroups_internal(new_cred, wcred->sc_supp_groups_nb, groups); } else if (flags & SETCREDF_GID) change_egid(new_cred, wcred->sc_gid); @@ -1206,6 +1218,7 @@ sys_setgroups(struct thread *td, struct setgroups_args *uap) * setgroups() differ. */ gidsetsize = uap->gidsetsize; + /* XXXKE Limit to ngroups_max when we change the userland interface. */ if (gidsetsize > ngroups_max + 1 || gidsetsize < 0) return (EINVAL); @@ -1233,17 +1246,29 @@ kern_setgroups(struct thread *td, int *ngrpp, gid_t *groups) struct proc *p = td->td_proc; struct ucred *newcred, *oldcred; int ngrp, error; + gid_t egid; ngrp = *ngrpp; /* Sanity check size. */ + /* XXXKE Limit to ngroups_max when we change the userland interface. */ if (ngrp < 0 || ngrp > ngroups_max + 1) return (EINVAL); AUDIT_ARG_GROUPSET(groups, ngrp); if (ngrp != 0) { /* We allow and treat 0 specially below. */ - groups_normalize(ngrpp, groups); - ngrp = *ngrpp; + + /* + * To maintain userland compat for now, we use the first group + * as our egid and we'll use the rest as our supplemental + * groups. + */ + egid = groups[0]; + ngrp--; + memmove(&groups[0], &groups[1], ngrp * sizeof(groups[0])); + + groups_normalize(&ngrp, groups); + *ngrpp = ngrp; } newcred = crget(); if (ngrp != 0) @@ -1253,8 +1278,8 @@ kern_setgroups(struct thread *td, int *ngrpp, gid_t *groups) #ifdef MAC error = ngrp == 0 ? - /* If 'ngrp' is 0, we'll keep just the current effective GID. */ - mac_cred_check_setgroups(oldcred, 1, oldcred->cr_groups) : + /* If 'ngrp' is 0, the group is empty now. */ + mac_cred_check_setgroups(oldcred, 0, NULL) : mac_cred_check_setgroups(oldcred, ngrp, groups); if (error) goto fail; @@ -1265,15 +1290,11 @@ kern_setgroups(struct thread *td, int *ngrpp, gid_t *groups) goto fail; if (ngrp == 0) { - /* - * setgroups(0, NULL) is a legitimate way of clearing the - * groups vector on non-BSD systems (which generally do not - * have the egid in the groups[0]). We risk security holes - * when running non-BSD software if we do not do the same. - */ - newcred->cr_ngroups = 1; - } else + newcred->cr_ngroups = 0; + } else { + newcred->cr_gid = egid; crsetgroups_internal(newcred, ngrp, groups); + } setsugid(p); proc_set_cred(p, newcred); @@ -1693,11 +1714,11 @@ groups_check_normalized(int ngrp, const gid_t *groups) groups_check_positive_len(ngrp); groups_check_max_len(ngrp); - if (ngrp == 1) + if (ngrp <= 1) return; - prev_g = groups[1]; - for (int i = 2; i < ngrp; ++i) { + prev_g = groups[0]; + for (int i = 1; i < ngrp; ++i) { const gid_t g = groups[i]; if (prev_g >= g) @@ -1723,7 +1744,7 @@ group_is_supplementary(const gid_t gid, const struct ucred *const cred) * Perform a binary search of the supplementary groups. This is * possible because we sort the groups in crsetgroups(). */ - return (bsearch(&gid, cred->cr_groups + 1, cred->cr_ngroups - 1, + return (bsearch(&gid, cred->cr_groups, cred->cr_ngroups, sizeof(gid), gidp_cmp) != NULL); } @@ -2588,11 +2609,6 @@ void crcopy(struct ucred *dest, struct ucred *src) { - /* - * Ideally, 'cr_ngroups' should be moved out of 'struct ucred''s bcopied - * area, but this would break the ABI, so is deferred until there is - * a compelling need to change it. - */ bcopy(&src->cr_startcopy, &dest->cr_startcopy, (unsigned)((caddr_t)&src->cr_endcopy - (caddr_t)&src->cr_startcopy)); @@ -2634,11 +2650,17 @@ cru2x(struct ucred *cr, struct xucred *xcr) bzero(xcr, sizeof(*xcr)); xcr->cr_version = XUCRED_VERSION; xcr->cr_uid = cr->cr_uid; + xcr->cr_gid = cr->cr_gid; - ngroups = MIN(cr->cr_ngroups, XU_NGROUPS); + /* + * We use a union to alias cr_gid to cr_groups[0] in the xucred, so + * this is kind of ugly; cr_ngroups still includes the egid for our + * purposes to avoid bumping the xucred version. + */ + ngroups = MIN(cr->cr_ngroups + 1, nitems(xcr->cr_groups)); xcr->cr_ngroups = ngroups; - bcopy(cr->cr_groups, xcr->cr_groups, - ngroups * sizeof(*cr->cr_groups)); + bcopy(cr->cr_groups, xcr->cr_sgroups, + (ngroups - 1) * sizeof(*cr->cr_groups)); } void @@ -2809,12 +2831,8 @@ crextend(struct ucred *cr, int n) /* * Normalizes a set of groups to be applied to a 'struct ucred'. * - * The set of groups is an array that must comprise the effective GID as its - * first element (so its length cannot be 0). - * - * Normalization ensures that elements after the first, which stand for the - * supplementary groups, are sorted in ascending order and do not contain - * duplicates. + * Normalization ensures that the supplementary groups are sorted in ascending + * order and do not contain duplicates. */ static void groups_normalize(int *ngrp, gid_t *groups) @@ -2825,15 +2843,15 @@ groups_normalize(int *ngrp, gid_t *groups) groups_check_positive_len(*ngrp); groups_check_max_len(*ngrp); - if (*ngrp == 1) + if (*ngrp <= 1) return; - qsort(groups + 1, *ngrp - 1, sizeof(*groups), gidp_cmp); + qsort(groups, *ngrp, sizeof(*groups), gidp_cmp); /* Remove duplicates. */ - prev_g = groups[1]; - ins_idx = 2; - for (int i = 2; i < *ngrp; ++i) { + prev_g = groups[0]; + ins_idx = 1; + for (int i = ins_idx; i < *ngrp; ++i) { const gid_t g = groups[i]; if (g != prev_g) { @@ -2876,7 +2894,7 @@ crsetgroups_internal(struct ucred *cr, int ngrp, const gid_t *groups) * Copy groups in to a credential after expanding it if required. * * May sleep in order to allocate memory (except if, e.g., crextend() was called - * before with 'ngrp' or greater). Truncates the list to (ngroups_max + 1) if + * before with 'ngrp' or greater). Truncates the list to ngroups_max if * it is too large. Array 'groups' doesn't need to be sorted. 'ngrp' must be * strictly positive. */ @@ -2884,8 +2902,8 @@ void crsetgroups(struct ucred *cr, int ngrp, const gid_t *groups) { - if (ngrp > ngroups_max + 1) - ngrp = ngroups_max + 1; + if (ngrp > ngroups_max) + ngrp = ngroups_max; /* * crextend() asserts that groups are not set, as it may allocate a new * backing storage without copying the content of the old one. Since we @@ -2893,9 +2911,11 @@ crsetgroups(struct ucred *cr, int ngrp, const gid_t *groups) * consider the old ones thrown away. */ cr->cr_ngroups = 0; - crextend(cr, ngrp); - crsetgroups_internal(cr, ngrp, groups); - groups_normalize(&cr->cr_ngroups, cr->cr_groups); + if (ngrp != 0) { + crextend(cr, ngrp); + crsetgroups_internal(cr, ngrp, groups); + groups_normalize(&cr->cr_ngroups, cr->cr_groups); + } } /* diff --git a/sys/rpc/authunix_prot.c b/sys/rpc/authunix_prot.c index 77d7a6c39e84..777699997272 100644 --- a/sys/rpc/authunix_prot.c +++ b/sys/rpc/authunix_prot.c @@ -96,9 +96,8 @@ xdr_authunix_parms(XDR *xdrs, uint32_t *time, struct xucred *cred) 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; + ngroups = cred->cr_ngroups; if (ngroups > NGRPS) ngroups = NGRPS; } @@ -106,8 +105,8 @@ 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 (!xdr_uint32_t(xdrs, &cred->cr_groups[i + 1])) + if (i < ngroups_max) { + if (!xdr_uint32_t(xdrs, &cred->cr_groups[i])) return (FALSE); } else { if (!xdr_uint32_t(xdrs, &junk)) @@ -116,10 +115,10 @@ xdr_authunix_parms(XDR *xdrs, uint32_t *time, struct xucred *cred) } if (xdrs->x_op == XDR_DECODE) { - if (ngroups + 1 > ngroups_max + 1) - cred->cr_ngroups = ngroups_max + 1; + if (ngroups > ngroups_max) + cred->cr_ngroups = ngroups_max; else - cred->cr_ngroups = ngroups + 1; + cred->cr_ngroups = ngroups; } return (TRUE); diff --git a/sys/rpc/svc_auth_unix.c b/sys/rpc/svc_auth_unix.c index b10ef33be704..a066187fcdb6 100644 --- a/sys/rpc/svc_auth_unix.c +++ b/sys/rpc/svc_auth_unix.c @@ -89,17 +89,16 @@ _svcauth_unix(struct svc_req *rqst, struct rpc_msg *msg) 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); + if (i < XU_NGROUPS) + xcr->cr_groups[i] = IXDR_GET_INT32(buf); else buf++; } - if (gid_len + 1 > XU_NGROUPS) + if (gid_len > XU_NGROUPS) xcr->cr_ngroups = XU_NGROUPS; else - xcr->cr_ngroups = gid_len + 1; + xcr->cr_ngroups = gid_len; /* * five is the smallest unix credentials structure - diff --git a/sys/sys/ucred.h b/sys/sys/ucred.h index ddd8f3ddb63d..cf1a78d87655 100644 --- a/sys/sys/ucred.h +++ b/sys/sys/ucred.h @@ -76,15 +76,12 @@ struct ucred { u_int cr_users; /* (c) proc + thread using this cred */ u_int cr_flags; /* credential flags */ struct auditinfo_addr cr_audit; /* Audit properties. */ + int cr_ngroups; /* number of groups */ #define cr_startcopy cr_uid uid_t cr_uid; /* effective user id */ uid_t cr_ruid; /* real user id */ uid_t cr_svuid; /* saved user id */ - /* - * XXXOC: On the next ABI change, please move 'cr_ngroups' out of the - * copied area (crcopy() already copes with this change). - */ - int cr_ngroups; /* number of groups */ + gid_t cr_gid; /* effective group id */ gid_t cr_rgid; /* real group id */ gid_t cr_svgid; /* saved group id */ struct uidinfo *cr_uidinfo; /* per euid resource consumption */ @@ -111,8 +108,20 @@ struct ucred { struct xucred { u_int cr_version; /* structure layout version */ uid_t cr_uid; /* effective user id */ - short cr_ngroups; /* number of groups */ - gid_t cr_groups[XU_NGROUPS]; /* groups */ + short cr_ngroups; /* number of groups (incl. cr_gid). */ + union { + /* + * Special little hack to avoid needing a cr_gid macro, which + * would cause problems if one were to use it with struct ucred + * which also has a cr_groups member. + */ + struct { + gid_t cr_gid; /* effective group id */ + gid_t cr_sgroups[XU_NGROUPS - 1]; + }; + + gid_t cr_groups[XU_NGROUPS]; /* groups */ + }; union { void *_cr_unused1; /* compatibility with old ucred */ pid_t cr_pid; @@ -120,9 +129,6 @@ struct xucred { }; #define XUCRED_VERSION 0 -/* This can be used for both ucred and xucred structures. */ -#define cr_gid cr_groups[0] - struct mac; /* * Structure to pass as an argument to the setcred() system call. diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c index e53d9fcbc5be..a516ab9727fa 100644 --- a/sys/ufs/ufs/ufs_vnops.c +++ b/sys/ufs/ufs/ufs_vnops.c @@ -2051,7 +2051,6 @@ ufs_mkdir( { #ifdef QUOTA struct ucred ucred, *ucp; - gid_t ucred_group; ucp = cnp->cn_cred; #endif /* @@ -2078,13 +2077,8 @@ 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_gid = ucred_group = dp->i_gid; + ucred.cr_gid = dp->i_gid; + ucred.cr_ngroups = 0; ucp = &ucred; } #endif @@ -2812,7 +2806,6 @@ ufs_makeinode(int mode, struct vnode *dvp, struct vnode **vpp, { #ifdef QUOTA struct ucred ucred, *ucp; - gid_t ucred_group; ucp = cnp->cn_cred; #endif /* @@ -2838,13 +2831,8 @@ 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_gid = ucred_group = pdir->i_gid; + ucred.cr_gid = pdir->i_gid; + ucred.cr_ngroups = 0; ucp = &ucred; #endif } else {