git: 09290c3a0c82 - main - cred: Hide internal flag CRED_FLAG_CAPMODE

From: Olivier Certner <olce_at_FreeBSD.org>
Date: Mon, 16 Dec 2024 14:45:20 UTC
The branch main has been updated by olce:

URL: https://cgit.FreeBSD.org/src/commit/?id=09290c3a0c82524138973b14f393379edf733753

commit 09290c3a0c82524138973b14f393379edf733753
Author:     Olivier Certner <olce@FreeBSD.org>
AuthorDate: 2024-07-16 16:07:40 +0000
Commit:     Olivier Certner <olce@FreeBSD.org>
CommitDate: 2024-12-16 14:42:29 +0000

    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
---
 bin/ps/print.c                   |  2 +-
 lib/libkvm/kvm_proc.c            |  6 ++++--
 sys/sys/ucred.h                  | 12 ++++++------
 usr.bin/procstat/procstat_cred.c |  2 +-
 4 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/bin/ps/print.c b/bin/ps/print.c
index 59631fb66a10..13ef646ea462 100644
--- a/bin/ps/print.c
+++ b/bin/ps/print.c
@@ -265,7 +265,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';
diff --git a/lib/libkvm/kvm_proc.c b/lib/libkvm/kvm_proc.c
index 6d2879f34d8f..b2b7c6ecce56 100644
--- a/lib/libkvm/kvm_proc.c
+++ b/lib/libkvm/kvm_proc.c
@@ -142,11 +142,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;
@@ -154,7 +157,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,
diff --git a/sys/sys/ucred.h b/sys/sys/ucred.h
index 75156cca09a5..25dff911241b 100644
--- a/sys/sys/ucred.h
+++ b/sys/sys/ucred.h
@@ -38,11 +38,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
@@ -96,10 +99,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.
diff --git a/usr.bin/procstat/procstat_cred.c b/usr.bin/procstat/procstat_cred.c
index 7f1efeab9d4c..decb7b9ca7df 100644
--- a/usr.bin/procstat/procstat_cred.c
+++ b/usr.bin/procstat/procstat_cred.c
@@ -62,7 +62,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:     }");