git: d36c8416e7ed - stable/15 - libprocstat: procstat_getgroups_kvm(): Output again the effective GID

From: Olivier Certner <olce_at_FreeBSD.org>
Date: Tue, 23 Sep 2025 12:03:25 UTC
The branch stable/15 has been updated by olce:

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

commit d36c8416e7ed6d02fd85dada19b40defc2a0f9f1
Author:     Olivier Certner <olce@FreeBSD.org>
AuthorDate: 2025-08-28 14:49:07 +0000
Commit:     Olivier Certner <olce@FreeBSD.org>
CommitDate: 2025-09-23 12:02:40 +0000

    libprocstat: procstat_getgroups_kvm(): Output again the effective GID
    
    In particular, fixes 'procstat -s -M' (for processes with more than 16
    groups).
    
    Reviewed by:    kib
    Fixes:          be1f7435ef218b1d ("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/D52275
    
    (cherry picked from commit 11cbb7d122ac0219c214ad52c4d6f7cbb9d60ac1)
---
 lib/libprocstat/libprocstat.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/lib/libprocstat/libprocstat.c b/lib/libprocstat/libprocstat.c
index 1651cbc6820f..df77cabcd36b 100644
--- a/lib/libprocstat/libprocstat.c
+++ b/lib/libprocstat/libprocstat.c
@@ -1973,6 +1973,7 @@ procstat_getgroups_kvm(kvm_t *kd, struct kinfo_proc *kp, unsigned int *cntp)
 	struct ucred ucred;
 	gid_t *groups;
 	size_t len;
+	unsigned int ngroups;
 
 	assert(kd != NULL);
 	assert(kp != NULL);
@@ -1990,19 +1991,22 @@ procstat_getgroups_kvm(kvm_t *kd, struct kinfo_proc *kp, unsigned int *cntp)
 		    proc.p_ucred, kp->ki_pid);
 		return (NULL);
 	}
-	len = ucred.cr_ngroups * sizeof(gid_t);
+	ngroups = 1 + ucred.cr_ngroups;
+	len = ngroups * sizeof(gid_t);
 	groups = malloc(len);
 	if (groups == NULL) {
 		warn("malloc(%zu)", len);
 		return (NULL);
 	}
-	if (!kvm_read_all(kd, (unsigned long)ucred.cr_groups, groups, len)) {
+	groups[0] = ucred.cr_gid;
+	if (!kvm_read_all(kd, (unsigned long)ucred.cr_groups, groups + 1,
+	    len - sizeof(gid_t))) {
 		warnx("can't read groups at %p for pid %d",
 		    ucred.cr_groups, kp->ki_pid);
 		free(groups);
 		return (NULL);
 	}
-	*cntp = ucred.cr_ngroups;
+	*cntp = ngroups;
 	return (groups);
 }