git: 8013a7137d3a - stable/15 - linux: Simplify further getgroups() after 'cr_gid' not in cr_groups[]

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

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

commit 8013a7137d3ac5d6f0f3386fe8531594bcb067be
Author:     Olivier Certner <olce@FreeBSD.org>
AuthorDate: 2025-08-28 15:29:33 +0000
Commit:     Olivier Certner <olce@FreeBSD.org>
CommitDate: 2025-09-23 12:02:44 +0000

    linux: Simplify further getgroups() after 'cr_gid' not in cr_groups[]
    
    No functional change (intended).
    
    While here, fix/improve style a bit and in setgroups().
    
    MFC after:      5 days
    MFC to:         stable/15
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D52276
    
    (cherry picked from commit a207833f4fed5431cac853c082fa34dc8f33cba6)
---
 sys/compat/linux/linux_misc.c  | 36 ++++++++++++++++--------------------
 sys/compat/linux/linux_uid16.c | 36 ++++++++++++++++--------------------
 2 files changed, 32 insertions(+), 40 deletions(-)

diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c
index 5e32353c6b8e..755eae057406 100644
--- a/sys/compat/linux/linux_misc.c
+++ b/sys/compat/linux/linux_misc.c
@@ -1028,18 +1028,19 @@ linux_nice(struct thread *td, struct linux_nice_args *args)
 int
 linux_setgroups(struct thread *td, struct linux_setgroups_args *args)
 {
+	const int ngrp = args->gidsetsize;
 	struct ucred *newcred, *oldcred;
 	l_gid_t *linux_gidset;
-	int ngrp, error;
+	int error;
 	struct proc *p;
 
-	ngrp = args->gidsetsize;
 	if (ngrp < 0 || ngrp >= ngroups_max)
 		return (EINVAL);
 	linux_gidset = malloc(ngrp * sizeof(*linux_gidset), M_LINUX, M_WAITOK);
 	error = copyin(args->grouplist, linux_gidset, ngrp * sizeof(l_gid_t));
 	if (error)
 		goto out;
+
 	newcred = crget();
 	crextend(newcred, ngrp);
 	p = td->td_proc;
@@ -1071,34 +1072,29 @@ out:
 int
 linux_getgroups(struct thread *td, struct linux_getgroups_args *args)
 {
-	struct ucred *cred;
+	const struct ucred *const cred = td->td_ucred;
 	l_gid_t *linux_gidset;
-	gid_t *bsd_gidset;
-	int bsd_gidsetsz, ngrp, error;
+	int ngrp, error;
 
-	cred = td->td_ucred;
-	bsd_gidset = cred->cr_groups;
-	bsd_gidsetsz = cred->cr_ngroups;
+	ngrp = args->gidsetsize;
 
-	if ((ngrp = args->gidsetsize) == 0) {
-		td->td_retval[0] = bsd_gidsetsz;
+	if (ngrp == 0) {
+		td->td_retval[0] = cred->cr_ngroups;
 		return (0);
 	}
-
-	if (ngrp < bsd_gidsetsz)
+	if (ngrp < cred->cr_ngroups)
 		return (EINVAL);
 
-	ngrp = 0;
-	linux_gidset = malloc(bsd_gidsetsz * sizeof(*linux_gidset),
-	    M_LINUX, M_WAITOK);
-	while (ngrp < bsd_gidsetsz) {
-		linux_gidset[ngrp] = bsd_gidset[ngrp];
-		ngrp++;
-	}
+	ngrp = cred->cr_ngroups;
+
+	linux_gidset = malloc(ngrp * sizeof(*linux_gidset), M_LINUX, M_WAITOK);
+	for (int i = 0; i < ngrp; ++i)
+		linux_gidset[i] = cred->cr_groups[i];
 
 	error = copyout(linux_gidset, args->grouplist, ngrp * sizeof(l_gid_t));
 	free(linux_gidset, M_LINUX);
-	if (error)
+
+	if (error != 0)
 		return (error);
 
 	td->td_retval[0] = ngrp;
diff --git a/sys/compat/linux/linux_uid16.c b/sys/compat/linux/linux_uid16.c
index 1d9a19916412..07430f5b399b 100644
--- a/sys/compat/linux/linux_uid16.c
+++ b/sys/compat/linux/linux_uid16.c
@@ -85,12 +85,12 @@ linux_lchown16(struct thread *td, struct linux_lchown16_args *args)
 int
 linux_setgroups16(struct thread *td, struct linux_setgroups16_args *args)
 {
+	const int ngrp = args->gidsetsize;
 	struct ucred *newcred, *oldcred;
 	l_gid16_t *linux_gidset;
-	int ngrp, error;
+	int error;
 	struct proc *p;
 
-	ngrp = args->gidsetsize;
 	if (ngrp < 0 || ngrp >= ngroups_max)
 		return (EINVAL);
 	linux_gidset = malloc(ngrp * sizeof(*linux_gidset), M_LINUX, M_WAITOK);
@@ -100,6 +100,7 @@ linux_setgroups16(struct thread *td, struct linux_setgroups16_args *args)
 		free(linux_gidset, M_LINUX);
 		return (error);
 	}
+
 	newcred = crget();
 	p = td->td_proc;
 	PROC_LOCK(p);
@@ -133,34 +134,29 @@ out:
 int
 linux_getgroups16(struct thread *td, struct linux_getgroups16_args *args)
 {
-	struct ucred *cred;
+	const struct ucred *const cred = td->td_ucred;
 	l_gid16_t *linux_gidset;
-	gid_t *bsd_gidset;
-	int bsd_gidsetsz, ngrp, error;
+	int ngrp, error;
 
-	cred = td->td_ucred;
-	bsd_gidset = cred->cr_groups;
-	bsd_gidsetsz = cred->cr_ngroups;
+	ngrp = args->gidsetsize;
 
-	if ((ngrp = args->gidsetsize) == 0) {
-		td->td_retval[0] = bsd_gidsetsz;
+	if (ngrp == 0) {
+		td->td_retval[0] = cred->cr_ngroups;
 		return (0);
 	}
-
-	if (ngrp < bsd_gidsetsz)
+	if (ngrp < cred->cr_ngroups)
 		return (EINVAL);
 
-	ngrp = 0;
-	linux_gidset = malloc(bsd_gidsetsz * sizeof(*linux_gidset),
-	    M_LINUX, M_WAITOK);
-	while (ngrp < bsd_gidsetsz) {
-		linux_gidset[ngrp] = bsd_gidset[ngrp];
-		ngrp++;
-	}
+	ngrp = cred->cr_ngroups;
+
+	linux_gidset = malloc(ngrp * sizeof(*linux_gidset), M_LINUX, M_WAITOK);
+	for (int i = 0; i < ngrp; ++i)
+		linux_gidset[i] = cred->cr_groups[i];
 
 	error = copyout(linux_gidset, args->gidset, ngrp * sizeof(l_gid16_t));
 	free(linux_gidset, M_LINUX);
-	if (error) {
+
+	if (error != 0) {
 		LIN_SDT_PROBE1(uid16, linux_getgroups16, copyout_error, error);
 		return (error);
 	}