diff options
| author | Kyle Evans <kevans@FreeBSD.org> | 2025-07-31 04:44:11 +0000 |
|---|---|---|
| committer | Kyle Evans <kevans@FreeBSD.org> | 2025-07-31 04:44:11 +0000 |
| commit | be1f7435ef218b1df35aebf3b90dd65ffd8bbe51 (patch) | |
| tree | 4ed85d64a46c0fafca250dd0e550ec9adf76c12e /sys/sys/ucred.h | |
| parent | 763a097c156f36830e774b3cc789f68c5d1ae601 (diff) | |
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. We really can't
change the ABI of xucred, so instead we alias the first member to the
`cr_gid` name and maintain the status quo.
This also fixes the Linux setgroups(2)/getgroups(2) implementation to
more cleanly preserve the group set, now that we don't need to special
case cr_groups[0].
__FreeBSD_version bumped for the `struct ucred` ABI break.
For relnotes: downstreams and out-of-tree modules absolutely must fix
any references to cr_groups[0] in their code. These are almost
exclusively incorrect in the new world, and cr_gid should be used
instead. There is a cr_gid macro available in earlier FreeBSD versions
that can be used to avoid having version-dependant conditionals to refer
to the effective group id. Surrounding code may need adjusted if it
peels off the first element of cr_groups and uses the others as the
supplemental groups, since the supplemental groups start at cr_groups[0]
now if &cr_groups[0] != &cr_gid.
Relnotes: yes (see last paragraph)
Co-authored-by: olce
Differential Revision: https://reviews.freebsd.org/D51489
Diffstat (limited to 'sys/sys/ucred.h')
| -rw-r--r-- | sys/sys/ucred.h | 26 |
1 files changed, 16 insertions, 10 deletions
diff --git a/sys/sys/ucred.h b/sys/sys/ucred.h index ddd8f3ddb63d..4831d8cb6e1b 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 supplementary 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. |
