[comp.bugs.4bsd] Real GID must not be forced into group list

gore@eecs.nwu.edu (Jacob Gore) (09/18/88)

In 4.3BSD, the real gid is automatically a member of the group list.  This
is a mistake.  It makes setregid(2) and access(2) useless.

This example (derived from a real problem I ran into) illustrates this
problem: 

----------------------------------
gore 2> cat test2.c
#include <sys/types.h>
#include <sys/file.h>

main(){
    int ret;
    uid_t ruid, euid;
    gid_t rgid, egid;

    ruid=getuid();	rgid=getgid();
    euid=geteuid();	egid=getegid();

    setreuid(euid, ruid);  setregid(egid, rgid);

    printf("uid=%d,\tgid=%d;\t\teuid=%d,\tegid=%d\n",
	   getuid(), getgid(), geteuid(), getegid());

    if (open("/tmp/jjj/aaa", O_RDWR|O_APPEND|O_CREAT, 0777) < 0) {
	perror("file");
    }

    setreuid(ruid, euid);  setregid(rgid, egid);

    printf("uid=%d,\tgid=%d;\t\teuid=%d,\tegid=%d\n",
	   getuid(), getgid(), geteuid(), getegid());
}
gore 2> ls -lg a.out
-rwxr-sr-x  1 notes    notes       11264 Sep 17 14:38 a.out
gore 2> ls -lgd /tmp/jjj
drwxrwxr-x  2 notes    notes         512 Sep 17 14:39 /tmp/jjj
gore 2> ls -lg /tmp/jjj
total 0
gore 2> whoami
gore
gore 2> groups
staff msgs tex lab
gore 2> ./a.out
uid=10003,	gid=7;		euid=10003,	egid=100
uid=10003,	gid=100;	euid=10003,	egid=7
gore 2> ls -lg /tmp/jjj
total 0
-rwxr-xr-x  1 gore     notes           0 Sep 17 14:40 aaa
gore 2> 
----------------------------------

The setregid() call does nothing to change the process's access privileges!
The privileges are in effect those provided by the union of real gid,
effective gid, and the group list, so swapping the real and the effective
gid's does nothing but change the names of the slots they are stored in.

This is more than just a problem with setregid() -- it also breaks
access(), as shown in the next test program:

----------------------------------
gore 2> cat test.c
#include <sys/file.h>

main(){
    int ret;
    if (access("/tmp/jjj/aaa", W_OK) < 0) perror("file");
    if (access("/tmp/jjj", W_OK) < 0) perror("directory");
}
gore 2> ls -lg a.out
-rwxr-sr-x  1 notes    notes        6144 Sep 17 14:52 a.out
gore 2> ls -lgd /tmp/jjj
drwxrwxr-x  2 notes    notes         512 Sep 17 14:40 /tmp/jjj
gore 2> ls -lg /tmp/jjj
total 0
gore 2> whoami
gore
gore 2> groups
staff msgs tex lab
gore 2> ./a.out
file: No such file or directory
gore 2> 
----------------------------------

This program should have executed both the 'perror("file")' AND the
'perror("directory")', because gore/{staff,msgs,tex,lab} is not allowed to
write in /tmp/jjj.


I thank Chris Torek <chris@mimsy.umd.edu> and Naim Abdullah
<naim@eecs.nwu.edu> for helping me pinpoint this problem.

Jacob Gore				Gore@EECS.NWU.Edu
Northwestern Univ., EECS Dept.		{oddjob,gargoyle,att}!nucsrl!gore