git: f0951233c6d3 - stable/13 - cr_canseeothergids(): Use real instead of effective group membership

From: Olivier Certner <olce_at_FreeBSD.org>
Date: Thu, 21 Dec 2023 13:43:41 UTC
The branch stable/13 has been updated by olce:

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

commit f0951233c6d33da3c9a6bc347d9ae7aa911d7ca9
Author:     Olivier Certner <olce.freebsd@certner.fr>
AuthorDate: 2023-08-17 23:54:45 +0000
Commit:     Olivier Certner <olce@FreeBSD.org>
CommitDate: 2023-12-21 13:38:07 +0000

    cr_canseeothergids(): Use real instead of effective group membership
    
    Using the effective group and not the real one when testing membership
    has the consequence that unprivileged processes cannot see setuid
    commands they launch until these have relinquished their privileges.
    This is also in contradiction with how the similar cr_canseeotheruids()
    works, i.e., by taking into account real user IDs.
    
    Fix this by substituting groupmember() with realgroupmember().  While
    here, simplify the code.
    
    PR:                     272093
    Reviewed by:            mhorne
    Sponsored by:           Kumacom SAS
    Differential Revision:  https://reviews.freebsd.org/D40642
    
    (cherry picked from commit 91658080f1a598ddda03943a783c9a941199f7d2)
    
    Approved by:    markj (mentor)
---
 sys/kern/kern_prot.c | 23 ++++++++++-------------
 1 file changed, 10 insertions(+), 13 deletions(-)

diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c
index e6c11d2ea74b..1c9e2927bc5e 100644
--- a/sys/kern/kern_prot.c
+++ b/sys/kern/kern_prot.c
@@ -1406,21 +1406,18 @@ SYSCTL_INT(_security_bsd, OID_AUTO, see_other_gids, CTLFLAG_RW,
 int
 cr_canseeothergids(struct ucred *u1, struct ucred *u2)
 {
-	int i, match;
-
 	if (!see_other_gids) {
-		match = 0;
-		for (i = 0; i < u1->cr_ngroups; i++) {
-			if (groupmember(u1->cr_groups[i], u2))
-				match = 1;
-			if (match)
-				break;
-		}
-		if (!match) {
-			if (priv_check_cred(u1, PRIV_SEEOTHERGIDS) != 0)
-				return (ESRCH);
-		}
+		if (realgroupmember(u1->cr_rgid, u2))
+			return (0);
+
+		for (int i = 1; i < u1->cr_ngroups; i++)
+			if (realgroupmember(u1->cr_groups[i], u2))
+				return (0);
+
+		if (priv_check_cred(u1, PRIV_SEEOTHERGIDS) != 0)
+			return (ESRCH);
 	}
+
 	return (0);
 }