sysdep: shortsetgroups - tryshsgr.c

Gerrit Pape <[email protected]> Mon, 20 Mar 2006 09:06:09 +0000
Newsgroups gmane.org.djb.miscellaneous
Message-ID <20060320090609.24588.qmail@0c16dc798cd512.315fe32.mid.smarden.org>
Hi,

it seems the check for the shortsetgroups sysdep isn't reliable.  E.g. on
Linux i386 and sparc with dietlibc, gid_t is short

 $ gcc -E dietlibc/include/sys/types.h |grep gid_t
     typedef unsigned short gid_t;
 $ 

When checking the sysdep as user that isn't a member of any supplementary
groups, it's fine

 # id
 uid=0(root) gid=0(root) groups=0(root)
 # cd djbdns-1.05
 # make hasshsgr.h >/dev/null 2>&1 && grep sysdep <hasshsgr.h
 /* sysdep: +shortsetgroups */
 # 

But when running as user that is member of multiple groups

 $ id
 uid=1000(pape) gid=1000(pape) groups=4(adm),1000(pape)
 $ make hasshsgr.h >/dev/null 2>&1 && grep sysdep <hasshsgr.h
 /* sysdep: -shortsetgroups */
 $ 

tryshsgr.c does

 if (getgroups(1,x) == -1) _exit(1);

which fails with EINVAL if the user is member of more than one group[0].

There's no impact on i386, the sysdep only is checked in prot.c

 #ifdef HASSHORTSETGROUPS
   short x[2];
   x[0] = gid; x[1] = 73; /* catch errors */
   if (setgroups(1,x) == -1) return -1;
 #else
   if (setgroups(1,&gid) == -1) return -1;
 #endif

But on sparc/dietlibc (big endian) prot_gid() will set group id always to
0 if the shortsetgroups sysdep got wrong in the build process.

Regards, Gerrit.

[0] http://www.opengroup.org/onlinepubs/009695399/functions/getgroups.html