From klyons@gt.corserv.com  Fri Feb 25 18:07:37 2005
Return-Path: <klyons@gt.corserv.com>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 24F2316A4CE
	for <FreeBSD-gnats-submit@freebsd.org>; Fri, 25 Feb 2005 18:07:37 +0000 (GMT)
Received: from gt.corserv.com (adsl-66-137-123-97.dsl.hstntx.swbell.net [66.137.123.97])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 9F80A43D46
	for <FreeBSD-gnats-submit@freebsd.org>; Fri, 25 Feb 2005 18:07:36 +0000 (GMT)
	(envelope-from klyons@gt.corserv.com)
Received: from gt.corserv.com (localhost.corserv.com [127.0.0.1])
	by gt.corserv.com (8.13.1/8.13.1) with ESMTP id j1PJF3vm001126
	for <FreeBSD-gnats-submit@freebsd.org>; Fri, 25 Feb 2005 13:15:03 -0600 (CST)
	(envelope-from klyons@gt.corserv.com)
Received: (from klyons@localhost)
	by gt.corserv.com (8.13.1/8.13.1/Submit) id j1PJF3oF001125;
	Fri, 25 Feb 2005 13:15:03 -0600 (CST)
	(envelope-from klyons)
Message-Id: <200502251915.j1PJF3oF001125@gt.corserv.com>
Date: Fri, 25 Feb 2005 13:15:03 -0600 (CST)
From: Kevin Lyons <klyons@corserv.com>
Reply-To: Kevin Lyons <klyons@corserv.com>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: groups program inconsistency	
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         78087
>Category:       bin
>Synopsis:       groups(1) program inconsistency
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Feb 25 18:10:21 GMT 2005
>Closed-Date:    Fri Oct 30 18:15:28 UTC 2009
>Last-Modified:  Fri Oct 30 18:15:28 UTC 2009
>Originator:     Kevin Lyons
>Release:        FreeBSD 5.3-RELEASE i386
>Organization:
>Environment:
System: FreeBSD gt.corserv.com 5.3-RELEASE FreeBSD 5.3-RELEASE #0: Fri Nov 5 04:19:18 UTC 2004 root@harlow.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC i386


>Description:
	The groups command behaves truncates the last two groups depending
	upon whether invoked with the user name as an arguement. Also
	group file access is denied for the last two groups, effectively
	limiting default group membership of a user to 14.
>How-To-Repeat:
	See attached text below.
>Fix:


--- rpt2 begins here ---

-output of ls -l of test directory.  note permissions and group of 1002 dir.---

total 10
drwxrwx---+ 6 root  foo1  512 Feb 25 11:58 1000
drwxrwx---+ 6 root  foo1  512 Feb 25 12:22 1001
drwxrwx---  6 root  foo1  512 Feb 25 11:20 1002

--- output of 'groups klyons' as user klyons ---

klyons wheel projects proj1000 it pm p001 p002 eng sr cs proj1001 proj1002 proj1003 foo1 foo2

--- output of 'groups' as user klyons ---

klyons wheel projects proj1000 it pm p001 p002 eng sr cs proj1001 proj1002 proj1003

----
Attempt at doing "cd 1002" fails with permission denied although according to
"groups klyons" command  that user is in the foo1 group.               


----  list of my /etc/group file for reference ----

# $FreeBSD: src/etc/group,v 1.31 2004/06/23 01:32:28 mlaier Exp $
#
wheel:*:0:root,klyons
daemon:*:1:
kmem:*:2:
sys:*:3:
tty:*:4:
operator:*:5:root
mail:*:6:
bin:*:7:
news:*:8:
man:*:9:
games:*:13:
staff:*:20:
sshd:*:22:
smmsp:*:25:
mailnull:*:26:
guest:*:31:
bind:*:53:
proxy:*:62:
authpf:*:63:
_pflogd:*:64:
uucp:*:66:
dialer:*:68:
network:*:69:
www:*:80:
nogroup:*:65533:
nobody:*:65534:
klyons:*:1001:
projects:*:8000:klyons
proj1000:*:8001:klyons
it:*:8002:klyons
pm:*:8003:klyons
p001:*:8004:klyons
p002:*:8005:klyons
eng:*:8006:klyons
sr:*:8007:klyons
cs:*:8008:klyons
proj1001:*:8009:klyons
proj1002:*:8010:klyons
proj1003:*:8011:klyons
foo1:*:8012:klyons
foo2:*:8013:klyons
foo3:*:8014:klyons
foo4:*:8015:klyons
foo5:*:8016:klyons
foo6:*:8017:klyons
foo7:*:8018:klyons
foo8:*:8019:klyons
foo9:*:8020:klyons
--- rpt2 ends here ---


>Release-Note:
>Audit-Trail:

From: Russ Francis <russell.francis@gmail.com>
To: FreeBSD-gnats-submit@freebsd.org
Cc: Kevin Lyons <klyons@corserv.com>
Subject: Re: bin/78087: groups program inconsistency
Date: Mon, 28 Feb 2005 02:04:59 +0000

 Kevin,
 
 I saw this report and 78087 which looks similar and thought they looked curious.
 
 I have tried to duplicate this issue without luck and am running 
 
 FreeBSD 5.3-RELEASE-p2
 
 bash-2.05b$ sysctl kern.ngroups
 kern.ngroups: 16
 
 relevant portion of /etc/group
 --- snip ---
 foouser:*:1004:
 foo1:*:20001:foouser
 foo2:*:20002:foouser
 foo3:*:20003:foouser
 foo4:*:20004:foouser
 foo5:*:20005:foouser
 foo6:*:20006:foouser
 foo7:*:20007:foouser
 foo8:*:20008:foouser
 foo9:*:20009:foouser
 foo10:*:20010:foouser
 foo11:*:20011:foouser
 foo12:*:20012:foouser
 foo13:*:20013:foouser
 foo14:*:20014:foouser
 #foo15:*:20015:foouser
 
 
 su-2.05b$ whoami
 foouser
 su-2.05b$ id
 uid=1004(foouser) gid=1004(foouser) groups=1004(foouser), 20001(foo1),
 20002(foo2), 20003(foo3), 20004(foo4), 20005(foo5), 20006(foo6),
 20007(foo7), 20008(foo8), 20009(foo9), 20010(foo10), 20011(foo11),
 20012(foo12), 20013(foo13), 20014(foo14)
 su-2.05b$ id foouser
 uid=1004(foouser) gid=1004(foouser) groups=1004(foouser), 20001(foo1),
 20002(foo2), 20003(foo3), 20004(foo4), 20005(foo5), 20006(foo6),
 20007(foo7), 20008(foo8), 20009(foo9), 20010(foo10), 20011(foo11),
 20012(foo12), 20013(foo13), 20014(foo14)
 
 When I uncomment the line '#foo15:*:20015:foouser' from /etc/group
 I get the following error
 
 bash-2.05b$ su foouser
 Password:
 su: setusercontext: Invalid argument
 
 My results are different from yours, but also seem like a bug.  I am
 only able to be assigned to 15 groups despite kern.ngroups being equal
 to 16?   What is kern.ngroups set at for you?
 
 Cheers,
 Russ

From: Bruce Evans <bde@zeta.org.au>
To: Russ Francis <russell.francis@gmail.com>
Cc: freebsd-gnats-submit@FreeBSD.org, dds@FreeBSD.org
Subject: Re: bin/78087: groups program inconsistency
Date: Wed, 2 Mar 2005 07:35:55 +1100 (EST)

 On Mon, 28 Feb 2005, Russ Francis wrote:
 
 > I saw this report and 78087 which looks similar and thought they looked curious.
 >
 > I have tried to duplicate this issue without luck and am running
 >
 > FreeBSD 5.3-RELEASE-p2
 >
 > bash-2.05b$ sysctl kern.ngroups
 > kern.ngroups: 16
 >
 > relevant portion of /etc/group
 > --- snip ---
 > foouser:*:1004:
 > foo1:*:20001:foouser
 > foo2:*:20002:foouser
 > foo3:*:20003:foouser
 > foo4:*:20004:foouser
 > foo5:*:20005:foouser
 > foo6:*:20006:foouser
 > foo7:*:20007:foouser
 > foo8:*:20008:foouser
 > foo9:*:20009:foouser
 > foo10:*:20010:foouser
 > foo11:*:20011:foouser
 > foo12:*:20012:foouser
 > foo13:*:20013:foouser
 > foo14:*:20014:foouser
 > #foo15:*:20015:foouser
 
 There is a longstanding off-by-1 bug or two concerning {NGROUPS_MAX}.
 POSIX specifies that {NGROUPS_MAX} gives the number of supplementary
 group ids *in addition* to the effective group id.  {NGROUPS_MAX} is
 16 in FreeBSD so you should be able to have up to foo16 in the above.
 This never worked in FreeBSD, so {NOGROUPS_MAX} is off-by-1.
 
 ISTR that there is another off-by-1 bug in setgroups(2) or in library
 callers of it.  I forget the details.
 
 > su-2.05b$ whoami
 > foouser
 > su-2.05b$ id
 > uid=1004(foouser) gid=1004(foouser) groups=1004(foouser), 20001(foo1),
 > 20002(foo2), 20003(foo3), 20004(foo4), 20005(foo5), 20006(foo6),
 > 20007(foo7), 20008(foo8), 20009(foo9), 20010(foo10), 20011(foo11),
 > 20012(foo12), 20013(foo13), 20014(foo14)
 > su-2.05b$ id foouser
 > uid=1004(foouser) gid=1004(foouser) groups=1004(foouser), 20001(foo1),
 > 20002(foo2), 20003(foo3), 20004(foo4), 20005(foo5), 20006(foo6),
 > 20007(foo7), 20008(foo8), 20009(foo9), 20010(foo10), 20011(foo11),
 > 20012(foo12), 20013(foo13), 20014(foo14)
 >
 > When I uncomment the line '#foo15:*:20015:foouser' from /etc/group
 > I get the following error
 >
 > bash-2.05b$ su foouser
 > Password:
 > su: setusercontext: Invalid argument
 
 There now seems to be an off-by-2 bug.  I have something like the
 above foo[1-15] in my /etc/group for just one user, for the purpose
 of running old POSIX tests (NIST PCTS) of {NGROUPS_MAX}.  This used
 to work, but I now get the above error from su.  login fails too,
 but doesn't print a message.  The POSIX tests only worked because
 I misconfigured them to hide the longstanding off-by-one error:
 
 % SUPPLEMENTARY_GROUPS    "0,1000,1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1011,1012,1013,1014"
 
 The account is supposed to have primary group 0 (wheel) and 16 supplementary
 groups 1000-1015, but #1015 doesn't work so I left it out of /etc/groups
 and fudged the tests to succeed by putting the primary group in the
 supplementary groups.
 
 The new bug is exposed by:
 
 % RCS file: /home/ncvs/src/lib/libc/gen/initgroups.c,v
 % Working file: initgroups.c
 % head: 1.8
 % ...
 % ----------------------------
 % revision 1.8
 % date: 2003/11/19 15:51:26;  author: dds;  state: Exp;  lines: +7 -2
 % Fix problem where initgroups would silently truncate groups with
 % more than NGROUP elements without providing the opportunity to
 % setgroups to fail and correctly return error and set errno.
 % 
 % MFC after:	2 weeks
 % ----------------------------
 % 
 % Index: initgroups.c
 % ===================================================================
 % RCS file: /home/ncvs/src/lib/libc/gen/initgroups.c,v
 % retrieving revision 1.7
 % retrieving revision 1.8
 % diff -u -2 -r1.7 -r1.8
 % --- initgroups.c	1 Feb 2002 00:57:29 -0000	1.7
 % +++ initgroups.c	19 Nov 2003 15:51:26 -0000	1.8
 % ...
 % @@ -51,7 +51,12 @@
 %  	gid_t agroup;
 %  {
 % -	int groups[NGROUPS], ngroups;
 % +	int ngroups;
 % +	/*
 % +	 * Provide space for one group more than NGROUPS to allow
 % +	 * setgroups to fail and set errno.
 % +	 */
 % +	gid_t groups[NGROUPS + 1];
 
 This has some style bugs.
 
 % 
 % -	ngroups = NGROUPS;
 % +	ngroups = NGROUPS + 1;
 %  	getgrouplist(uname, agroup, groups, &ngroups);
 %  	return (setgroups(ngroups, groups));
 
 getgrouplist() puts `agroup' in groups[0] and groups[1], so there are
 only 14 slots left for the supplementary groups.  Thus when there are
 15 supplementary groups all different from `agroup', the above change
 makes ngroups = 17 and setgroups() fails.  Immediately before the above
 change, the last group was just discarded so it couldn't have worked,
 but think PCTS would have found the bug if the last group had not worked
 long ago.
 
 getgrouplist() has to put `agroup' in groups[0] because the group list
 has to include the primary group in FreeBSD due to a dubious efficiency
 hack in the implementation -- in FreeBSD, the effective group id is
 just groups[0].  This efficiency hacks is what gives the first off-by-1
 error -- {NGROUPS_MAX} iis missing the adjustment for the hack.
 
 getgrouplist() normally puts `agroup' in groups[1] according to the
 following comment:
 
 % 	/*
 % 	 * When installing primary group, duplicate it;
 % 	 * the first element of groups is the effective gid
 % 	 * and will be overwritten when a setgid file is executed.
 % 	 */
 
 I don't understand why this is needed.  It obviously increments the off-by-1
 error count, since the setgroups(2) up immediately in the kernel if the
 groups count exceeds {NGROUPS_MAX}.
 
 getgrouplist() has changed signficantly near this bug since rev.1.1, but
 the change only reduces the bugs:
 
 % Index: getgrouplist.c
 % ===================================================================
 % RCS file: /home/ncvs/src/lib/libc/gen/getgrouplist.c,v
 % retrieving revision 1.1
 % retrieving revision 1.13
 % diff -u -2 -r1.1 -r1.13
 % --- getgrouplist.c	27 May 1994 04:56:40 -0000	1.1
 % +++ getgrouplist.c	16 Feb 2003 17:29:09 -0000	1.13
 % ...
 % @@ -70,17 +70,21 @@
 %  	 */
 %  	setgrent();
 % -	while (grp = getgrent()) {
 % -		if (grp->gr_gid == agroup)
 % -			continue;
 % -		if (ngroups >= maxgroups) {
 % -			ret = -1;
 % -			break;
 % +	while ((grp = getgrent()) != NULL) {
 % +		for (i = 0; i < ngroups; i++) {
 % +			if (grp->gr_gid == groups[i])
 % +				goto skip;
 
 Now getgrouplist() avoids wasting slots for duplicates in all cases
 after the first 1 or 2 slots, where it use to only avoid duplicates of
 `agroup'.  Avoiding duplicates allows {NGROUPS_MAX} groups to actually
 work in some cases, but cases where there are even {NGROUPS_MAX} - 1
 different groups all different from `agroup' apparently never worked.
 
 The kernel doesn't do any duplicate removal but probably should.
 POSIX doesn't specify setgroups(), but it specifies getgroups(2).
 For getgroups(), it is implementation-defined whether the effective
 group is returned, and applications must be prepared for
 {NGROUPS_MAX} + 1 gids being reurned.  FreeBSD does return the
 egid in the array.  FreeBSD's setgroups needs the egid in slot 0
 in the array.
 
 Bruce
State-Changed-From-To: open->closed 
State-Changed-By: brooks 
State-Changed-When: Fri Oct 30 18:02:58 UTC 2009 
State-Changed-Why:  


http://www.freebsd.org/cgi/query-pr.cgi?pr=78087 
State-Changed-From-To: closed->open 
State-Changed-By: brooks 
State-Changed-When: Fri Oct 30 18:03:37 UTC 2009 
State-Changed-Why:  
Reopen.  Previous closure lacked an appropriate message. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=78087 
State-Changed-From-To: open->closed 
State-Changed-By: brooks 
State-Changed-When: Fri Oct 30 18:06:13 UTC 2009 
State-Changed-Why:  
In 8.0 we have resolve the off-by-1 bug were we supported NGROUPS_MAX 
total groups instead of NGROUPS_MAX+1 groups along with raising 
NGROUPS_MAX to 1023. 

I think that getgrouplist is probably correct in duplicating the 
egid, at least not doing so would probably violate POLA for sgid 
programs that's probably a bad thing to do.  As such I am closing 
this PR. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=78087 
>Unformatted:
