cred: Hide internal flag CRED_FLAG_CAPMODE

This flag is used in field 'cr_flags', which is never directly visible
outside the kernel.  That field is however exported through 'struct
kinfo_proc' objects (field 'ki_cr_flags'), either from the kernel via
sysctls or from libkvm, and is supposed to contain exported flags
prefixed with KI_CRF_ (currently, KI_CRF_CAPABILITY_MODE and
KI_CRF_GRP_OVERFLOW, this second one being a purely userland one
signaling overflow of 'ki_groups').

Make sure that KI_CRF_CAPABILITY_MODE is the flag actually exported and
tested by userland programs, and hide the internal CRED_FLAG_CAPMODE.
As both flags are currently defined to the same value, this doesn't
change the KBI, but of course does change the KPI.  A code search via
GitHub and Google fortunately doesn't reveal any outside uses for
CRED_FLAG_CAPMODE.

While here, move assignment of 'ki_uid' to a more logical place in
kvm_proclist(), and definition of XU_NGROUPS as well in 'sys/ucred.h'
(no functional/interface changes intended).

Reviewed by:    mhorne
Approved by:    markj (mentor)
MFC after:      2 weeks
Sponsored by:   The FreeBSD Foundation
Differential Revision:  https://reviews.freebsd.org/D46909

(cherry picked from commit 09290c3a0c82524138973b14f393379edf733753)

A ports exp-run (PR 283410) showed one port to be affected
(sysutils/procs), which has been fixed upstream and in the ports tree.
All additional indirect references to CRED_FLAG_CAPMODE we found after
the code search mentioned in the original commit message are
automatically generated from our headers by FFI mechanisms, so
automatically disappear at recompilation (and the KBI is not changed, as
explained above, so recompilation is not needed).
This commit is contained in:
Olivier Certner 2024-07-16 18:07:40 +02:00
parent 9c84aea414
commit f9fa6cb391
No known key found for this signature in database
GPG key ID: 8CA13040971E2627
4 changed files with 12 additions and 10 deletions

View file

@ -275,7 +275,7 @@ state(KINFO *k, VARENT *ve __unused)
*cp++ = 'V';
if ((flag & P_SYSTEM) || k->ki_p->ki_lock > 0)
*cp++ = 'L';
if ((k->ki_p->ki_cr_flags & CRED_FLAG_CAPMODE) != 0)
if ((k->ki_p->ki_cr_flags & KI_CRF_CAPABILITY_MODE) != 0)
*cp++ = 'C';
if (k->ki_p->ki_kiflag & KI_SLEADER)
*cp++ = 's';

View file

@ -144,11 +144,14 @@ kvm_proclist(kvm_t *kd, int what, int arg, struct proc *p,
if (proc.p_state == PRS_NEW)
continue;
if (KREAD(kd, (u_long)proc.p_ucred, &ucred) == 0) {
kp->ki_uid = ucred.cr_uid;
kp->ki_ruid = ucred.cr_ruid;
kp->ki_svuid = ucred.cr_svuid;
kp->ki_rgid = ucred.cr_rgid;
kp->ki_svgid = ucred.cr_svgid;
kp->ki_cr_flags = ucred.cr_flags;
kp->ki_cr_flags = 0;
if (ucred.cr_flags & CRED_FLAG_CAPMODE)
kp->ki_cr_flags |= KI_CRF_CAPABILITY_MODE;
if (ucred.cr_ngroups > KI_NGROUPS) {
kp->ki_ngroups = KI_NGROUPS;
kp->ki_cr_flags |= KI_CRF_GRP_OVERFLOW;
@ -156,7 +159,6 @@ kvm_proclist(kvm_t *kd, int what, int arg, struct proc *p,
kp->ki_ngroups = ucred.cr_ngroups;
kvm_read(kd, (u_long)ucred.cr_groups, kp->ki_groups,
kp->ki_ngroups * sizeof(gid_t));
kp->ki_uid = ucred.cr_uid;
if (ucred.cr_prison != NULL) {
if (KREAD(kd, (u_long)ucred.cr_prison, &pr)) {
_kvm_err(kd, kd->program,

View file

@ -41,11 +41,14 @@
#endif
#include <bsm/audit.h>
#if defined(_KERNEL) || defined(_WANT_UCRED)
struct loginclass;
#define XU_NGROUPS 16
/*
* Flags for cr_flags.
*/
#define CRED_FLAG_CAPMODE 0x00000001 /* In capability mode. */
#if defined(_KERNEL) || defined(_WANT_UCRED)
/*
* Number of groups inlined in 'struct ucred'. It must stay reasonably low as
* it is also used by some functions to allocate an array of this size on the
@ -103,10 +106,7 @@ struct ucred {
#define FSCRED ((struct ucred *)-1) /* filesystem credential */
#endif /* _KERNEL || _WANT_UCRED */
/*
* Flags for cr_flags.
*/
#define CRED_FLAG_CAPMODE 0x00000001 /* In capability mode. */
#define XU_NGROUPS 16
/*
* This is the external representation of struct ucred.

View file

@ -63,7 +63,7 @@ procstat_cred(struct procstat *procstat, struct kinfo_proc *kipp)
xo_emit("{:rgid/%5d} ", kipp->ki_rgid);
xo_emit("{:svgid/%5d} ", kipp->ki_svgid);
xo_emit("{:umask/%5s} ", get_umask(procstat, kipp));
xo_emit("{:cr_flags/%s}", kipp->ki_cr_flags & CRED_FLAG_CAPMODE ?
xo_emit("{:cr_flags/%s}", kipp->ki_cr_flags & KI_CRF_CAPABILITY_MODE ?
"C" : "-");
xo_emit("{P: }");