unix: SCM_CREDS: Restore passing the effective GID

cmcred_groups[0] in 'struct cmsgcred' must be the effective GID.

Note that the code in unp_addsockcred() filling up 'struct
sockcred'/'struct sockcred2' (LOCAL_CREDS/LOCAL_CREDS_PERSISTENT
options) was in fact "wrong" before 'cr_gid' was moved out of
cr_groups[], in the sense that it would transmit the effective GID
twice, both separately as 'sc_egid' and as the first element of
'sc_groups'.  It is now exact, so is left unchanged, which causes
a difference in output (the effective GID is no more in 'sc_groups',
unless it is also a supplementary group) that is unlikely to affect
applications in practice.

Reviewed by:    glebius
Fixes:          be1f7435ef ("kern: start tracking cr_gid outside of cr_groups[]")
MFC after:      5 days
MFC to:         stable/15
Sponsored by:   The FreeBSD Foundation
Differential Revision:  https://reviews.freebsd.org/D52262
This commit is contained in:
Olivier Certner
2025-08-26 19:01:03 +02:00
parent 11cbb7d122
commit c5e920e49c
+6 -3
View File
@@ -3667,11 +3667,14 @@ unp_internalize(struct mbuf *control, struct mchain *mc, struct thread *td)
cmcred->cmcred_uid = td->td_ucred->cr_ruid;
cmcred->cmcred_gid = td->td_ucred->cr_rgid;
cmcred->cmcred_euid = td->td_ucred->cr_uid;
cmcred->cmcred_ngroups = MIN(td->td_ucred->cr_ngroups,
_Static_assert(CMGROUP_MAX >= 1,
"Room needed for the effective GID.");
cmcred->cmcred_ngroups = MIN(td->td_ucred->cr_ngroups + 1,
CMGROUP_MAX);
for (i = 0; i < cmcred->cmcred_ngroups; i++)
cmcred->cmcred_groups[0] = td->td_ucred->cr_gid;
for (i = 1; i < cmcred->cmcred_ngroups; i++)
cmcred->cmcred_groups[i] =
td->td_ucred->cr_groups[i];
td->td_ucred->cr_groups[i - 1];
break;
case SCM_RIGHTS: