Doing away with NGROUPS_MAX in src/sys/sys/syslimits.h?
n0g0013
ttw+bsd at cobbled.net
Tue Mar 24 04:09:30 PDT 2009
On 23.03-12:23, Boris Kochergin wrote:
[ ... ]
> >yes, that's great but you may be surprised to learn that it doesn't
> >actually solve your problem. i think (and without looking
> >specifically at the impact my even be confident enough to say
> >definately) if you get a groups list it will only be cropped and the
> >error message is being erroneously avoided, not corrected. i'd also
> >suggest that you may be opening up your system to some overflows
> >although, generally, the code sections use the same limits and so
> >you might get away with it.
[ ... ]
> On my 7.0 system, and a kernel recompiled with NGROUPS_MAX set to 64, a
> getgrouplist() call for a user who is in more than 16 groups (24, to be
> exact) will populate the array specified by the "gid_t *groups" argument
> with the 24 groups the user is in, in addition to the group specified in
> the "gid_t basegid" argument. The value of the variable specified in the
> "int *ngroups" will also be 25, and the getgrouplist() call will return
> 0. So, as far as being a hack for a specific problem, it seems to work
> properly.
yeah, looked at it now. NGROUPS is defined from NGROUPS_MAX (bad
memory). the other significant values would be KI_NGROUPS which is
not defined from NGROUPS_MAX; neither are the IPC or RPC relevant
values, although, as i said they use their own max values for validation
(i.e. they don't suddenly using NGROUPS_MAX instead of CMGROUPS) so
probably won't overflow trivially but i wouldn't say they are
necissarily safe.
suffice to say if it works for you great but be aware that you may
have security and other issues associated with the change.
[ ... ]
> Sure, I'll test the patch. Can you point me at it?
sure, attached. but note it's functionally zero progress, it only
looks to remove the dependancy on NGROUPS_MAX as static definition
and make SC_NGROUPS_MAX a writable and referenced value. however, it
won't currently give you the extra groups you want because it defines
other values from _NGROUP_COMPAT (which is 16) until i can complete
the changes to a stable state.
it would still be nice to know that i haven't messed it up
completely and that, at the very least the system still boots and
runs with it.
p.s: i've gotta finish some bloody web stuff and then i'll throw
some more time at it this afternoon.
--
t
t
w
-------------- next part --------------
Index: contrib/openpam/lib/openpam_borrow_cred.c
===================================================================
RCS file: /home/__orole/dev/cabinet/zeeNi/ai/freebsd/src/contrib/openpam/lib/openpam_borrow_cred.c,v
retrieving revision 1.1.1.9
diff -b -u -r1.1.1.9 openpam_borrow_cred.c
--- contrib/openpam/lib/openpam_borrow_cred.c 21 Dec 2007 11:49:29 -0000 1.1.1.9
+++ contrib/openpam/lib/openpam_borrow_cred.c 4 Feb 2009 16:38:46 -0000
@@ -60,6 +60,7 @@
struct pam_saved_cred *scred;
const void *scredp;
int r;
+ int ngroups ;
ENTERI(pwd->pw_uid);
r = pam_get_data(pamh, PAM_SAVED_CRED, &scredp);
@@ -73,26 +74,55 @@
(int)geteuid());
RETURNC(PAM_PERM_DENIED);
}
- scred = calloc(1, sizeof *scred);
- if (scred == NULL)
- RETURNC(PAM_BUF_ERR);
- scred->euid = geteuid();
- scred->egid = getegid();
- r = getgroups(NGROUPS_MAX, scred->groups);
- if (r < 0) {
- FREE(scred);
- RETURNC(PAM_SYSTEM_ERR);
- }
- scred->ngroups = r;
+/* get the maximum number of system groups */
+#if _POSIX_VERSION > 199212
+ ngroups = sysconf( _SC_NGROUPS_MAX ) ;
+#elif defined(NGROUPS_MAX)
+ ngroups = NGROUPS_MAX ;
+#else
+ ngroups = _NGROUPS_COMPAT ;
+#endif
+/* initally allocate enough memory for max_groups */
+ scred = malloc( sizeof(struct pam_saved_cred) +
+ ngroups*sizeof(gid_t) ) ;
+ if( scred == NULL )
+ RETURNC( PAM_BUF_ERR ) ;
+/* set the save values */
+ scred->euid = geteuid() ;
+ scred->egid = getegid() ;
+/* save groups into our (probably) oversized memory allocation */
+ r = getgroups( ngroups, scred->groups ) ;
+ if( r < 0 ) {
+ FREE( scred ) ; /* call PAM's free macro */
+ RETURNC( PAM_SYSTEM_ERR ) ;
+ } ;
+ scred->ngroups = r ;
+ ngroups = r < ngroups ? r : ngroups ; /* choose the smallest */
+ /* ... number of groups to allocate */
+ ngroups = ngroups < _NGROUPS_COMPAT ? ngroups : _NGROUPS_COMPAT ;
+ /* but keep it within expected minimum value */
+ /* XXX: we don't really want this but until we get
+ * educated on the implications this is probably safe
+ * and certainaly compatible */
+/* realloc, releasing unneeded memory */
+ scred = realloc( (void*)scred,
+ sizeof(struct pam_saved_cred)+ngroups*sizeof(gid_t) ) ;
+ /* nb: we ignore failure and try to store the larger
+ * ... structure as initially requested. catching the
+ * ... error in 'pam_set_data' if neccessary. */
+/* save the credentials to PAM user data area */
r = pam_set_data(pamh, PAM_SAVED_CRED, scred, &openpam_free_data);
if (r != PAM_SUCCESS) {
FREE(scred);
RETURNC(r);
}
+/* set the new credentials */
if (geteuid() == pwd->pw_uid)
RETURNC(PAM_SUCCESS);
if (initgroups(pwd->pw_name, pwd->pw_gid) < 0 ||
- setegid(pwd->pw_gid) < 0 || seteuid(pwd->pw_uid) < 0) {
+ setegid(pwd->pw_gid) < 0 || seteuid(pwd->pw_uid) < 0)
+ {
+ /* if any of the set calls failed, then restore and fail */
openpam_restore_cred(pamh);
RETURNC(PAM_SYSTEM_ERR);
}
Index: contrib/openpam/lib/openpam_impl.h
===================================================================
RCS file: /home/__orole/dev/cabinet/zeeNi/ai/freebsd/src/contrib/openpam/lib/openpam_impl.h,v
retrieving revision 1.1.1.17
diff -b -u -r1.1.1.17 openpam_impl.h
--- contrib/openpam/lib/openpam_impl.h 21 Dec 2007 11:49:29 -0000 1.1.1.17
+++ contrib/openpam/lib/openpam_impl.h 5 Feb 2009 15:41:19 -0000
@@ -110,13 +110,17 @@
int env_size;
};
-#ifdef NGROUPS_MAX
+#if _POSIX_VERSION > 199212
#define PAM_SAVED_CRED "pam_saved_cred"
struct pam_saved_cred {
uid_t euid;
gid_t egid;
- gid_t groups[NGROUPS_MAX];
int ngroups;
+ gid_t groups[];
+ /* keep this last so that we can simply
+ .. over-allocate the amount of space
+ .. nb: don't use sizeof' unless you adjust
+ .. for the number of groups */
};
#endif
Index: include/rpc/auth_unix.h
===================================================================
RCS file: /home/__orole/dev/cabinet/zeeNi/ai/freebsd/src/include/rpc/auth_unix.h,v
retrieving revision 1.11
diff -b -u -r1.11 auth_unix.h
--- include/rpc/auth_unix.h 23 Mar 2002 17:24:55 -0000 1.11
+++ include/rpc/auth_unix.h 14 Jan 2009 11:15:21 -0000
@@ -52,7 +52,7 @@
#define MAX_MACHINE_NAME 255
/* gids compose part of a credential; there may not be more than 16 of them */
-#define NGRPS 16
+#define AUTH_UNIX_NGROUPS 16
/*
* Unix style credentials.
Index: lib/libc/rpc/auth_unix.c
===================================================================
RCS file: /home/__orole/dev/cabinet/zeeNi/ai/freebsd/src/lib/libc/rpc/auth_unix.c,v
retrieving revision 1.18
diff -b -u -r1.18 auth_unix.c
--- lib/libc/rpc/auth_unix.c 14 Jun 2007 20:07:35 -0000 1.18
+++ lib/libc/rpc/auth_unix.c 4 Feb 2009 15:31:57 -0000
@@ -182,27 +182,48 @@
* Returns an auth handle with parameters determined by doing lots of
* syscalls.
*/
-AUTH *
+AUTH*
authunix_create_default()
{
- int len;
char machname[MAXHOSTNAMELEN + 1];
+ AUTH* auth_unix ;
uid_t uid;
gid_t gid;
- gid_t gids[NGROUPS_MAX];
-
- if (gethostname(machname, sizeof machname) == -1)
- abort();
- machname[sizeof(machname) - 1] = 0;
+ gid_t *gids ;
+ uint ngroups ;
+ uint max_ngroups ;
+
+/* get hostname or fail */
+ if( gethostname(machname,sizeof(machname)) == -1 )
+ abort() ;
+ machname[sizeof(machname)-1] = 0 ; /* add a null terminator */
+/* set uid/gid from current effective values */
uid = geteuid();
gid = getegid();
- if ((len = getgroups(NGROUPS_MAX, gids)) < 0)
- abort();
- if (len > NGRPS)
- len = NGRPS;
- /* XXX: interface problem; those should all have been unsigned */
- return (authunix_create(machname, (int)uid, (int)gid, len,
- (int *)gids));
+/* set the group set */
+#if _POSIX_VERSION > 199212
+ max_ngroups = sysconf( _SC_NGROUPS_MAX ) ;
+#elif defined(NGROUPS_MAX)
+ max_ngroups = NGROUPS_MAX ;
+#else
+ max_ngroups = 16 ;
+#endif
+ gids = (gid_t*)calloc( max_ngroups, sizeof(gid_t) ) ;
+ if( gids == NULL )
+ abort () ;
+ if( (ngroups=getgroups(max_ngroups,gids)) < 0 ) {
+ free( gids ) ;
+ abort() ;
+ }
+/* clip the groups to a transmissable size */
+ if( ngroups > AUTH_UNIX_NGROUPS )
+ ngroups = AUTH_UNIX_NGROUPS ;
+/* XXX: interface problem; those should all have been unsigned */
+ auth_unix = authunix_create( machname,
+ (int)uid, (int)gid, (int)ngroups,
+ (int*)gids ) ;
+ free( (void*)gids ) ;
+ return( auth_unix ) ;
}
/*
Index: lib/libc/rpc/authunix_prot.c
===================================================================
RCS file: /home/__orole/dev/cabinet/zeeNi/ai/freebsd/src/lib/libc/rpc/authunix_prot.c,v
retrieving revision 1.10
diff -b -u -r1.10 authunix_prot.c
--- lib/libc/rpc/authunix_prot.c 20 Nov 2007 01:51:20 -0000 1.10
+++ lib/libc/rpc/authunix_prot.c 4 Feb 2009 16:03:29 -0000
@@ -67,13 +67,14 @@
paup_gids = &p->aup_gids;
- if (xdr_u_long(xdrs, &(p->aup_time))
- && xdr_string(xdrs, &(p->aup_machname), MAX_MACHINE_NAME)
- && xdr_int(xdrs, &(p->aup_uid))
- && xdr_int(xdrs, &(p->aup_gid))
- && xdr_array(xdrs, (char **) paup_gids,
- &(p->aup_len), NGRPS, sizeof(int), (xdrproc_t)xdr_int) ) {
- return (TRUE);
+ if( xdr_u_long(xdrs,&(p->aup_time)) &&
+ xdr_string(xdrs,&(p->aup_machname),MAX_MACHINE_NAME) &&
+ xdr_int(xdrs,&(p->aup_uid)) &&
+ xdr_int(xdrs,&(p->aup_gid)) &&
+ xdr_array(xdrs,(char**)paup_gids,&(p->aup_len),
+ AUTH_UNIX_NGROUPS,sizeof(int),(xdrproc_t)xdr_int) )
+ {
+ return( TRUE ) ;
}
- return (FALSE);
+ return( FALSE ) ;
}
Index: lib/libc/rpc/netname.c
===================================================================
RCS file: /home/__orole/dev/cabinet/zeeNi/ai/freebsd/src/lib/libc/rpc/netname.c,v
retrieving revision 1.8
diff -b -u -r1.8 netname.c
--- lib/libc/rpc/netname.c 16 Oct 2004 06:11:35 -0000 1.8
+++ lib/libc/rpc/netname.c 14 Jan 2009 01:29:47 -0000
@@ -61,6 +61,7 @@
#ifndef MAXHOSTNAMELEN
#define MAXHOSTNAMELEN 256
#endif
+
#ifndef NGROUPS
#define NGROUPS 16
#endif
Index: lib/libc/rpc/netnamer.c
===================================================================
RCS file: /home/__orole/dev/cabinet/zeeNi/ai/freebsd/src/lib/libc/rpc/netnamer.c,v
retrieving revision 1.12
diff -b -u -r1.12 netnamer.c
--- lib/libc/rpc/netnamer.c 10 Mar 2005 00:58:21 -0000 1.12
+++ lib/libc/rpc/netnamer.c 3 Feb 2009 17:55:48 -0000
@@ -69,7 +69,6 @@
#ifndef NGROUPS
#define NGROUPS 16
#endif
-
/*
* Convert network-name into unix credential
*/
@@ -104,7 +103,7 @@
return (0);
}
*gidp = (gid_t) atol(p);
- for (gidlen = 0; gidlen < NGROUPS; gidlen++) {
+ for (gidlen = 0; gidlen < _NGROUPS_RPC_MAX; gidlen++) {
p = strsep(&res, "\n,");
if (p == NULL)
break;
@@ -157,7 +156,7 @@
static int
_getgroups(uname, groups)
char *uname;
- gid_t groups[NGROUPS];
+ gid_t groups[_NGROUPS_RPC_MAX];
{
gid_t ngroups = 0;
struct group *grp;
@@ -169,10 +168,11 @@
while ((grp = getgrent())) {
for (i = 0; grp->gr_mem[i]; i++)
if (!strcmp(grp->gr_mem[i], uname)) {
- if (ngroups == NGROUPS) {
+ if( ngroups == _NGROUPS_RPC_MAX ) {
#ifdef DEBUG
- fprintf(stderr,
- "initgroups: %s is in too many groups\n", uname);
+ fprintf( stderr,
+ "initgroups: %s is in too many groups\n",
+ uname ) ;
#endif
goto toomany;
}
Index: lib/libc/rpc/svc_auth_des.c
===================================================================
RCS file: /home/__orole/dev/cabinet/zeeNi/ai/freebsd/src/lib/libc/rpc/svc_auth_des.c,v
retrieving revision 1.9
diff -b -u -r1.9 svc_auth_des.c
--- lib/libc/rpc/svc_auth_des.c 22 Mar 2002 23:18:37 -0000 1.9
+++ lib/libc/rpc/svc_auth_des.c 3 Feb 2009 17:51:01 -0000
@@ -452,7 +452,7 @@
short uid; /* cached uid */
short gid; /* cached gid */
short grouplen; /* length of cached groups */
- short groups[NGROUPS]; /* cached groups */
+ short groups[_NGROUPS_RPC_MAX]; /* cached groups */
};
/*
Index: lib/libc/rpc/svc_auth_unix.c
===================================================================
RCS file: /home/__orole/dev/cabinet/zeeNi/ai/freebsd/src/lib/libc/rpc/svc_auth_unix.c,v
retrieving revision 1.11
diff -b -u -r1.11 svc_auth_unix.c
--- lib/libc/rpc/svc_auth_unix.c 16 Oct 2004 06:11:35 -0000 1.11
+++ lib/libc/rpc/svc_auth_unix.c 4 Feb 2009 16:04:10 -0000
@@ -68,7 +68,7 @@
struct area {
struct authunix_parms area_aup;
char area_machname[MAX_MACHINE_NAME+1];
- int area_gids[NGRPS];
+ int area_gids[AUTH_UNIX_NGROUPS] ;
} *area;
u_int auth_len;
size_t str_len, gid_len;
@@ -98,7 +98,7 @@
aup->aup_uid = (int)IXDR_GET_INT32(buf);
aup->aup_gid = (int)IXDR_GET_INT32(buf);
gid_len = (size_t)IXDR_GET_U_INT32(buf);
- if (gid_len > NGRPS) {
+ if( gid_len > AUTH_UNIX_NGROUPS ) {
stat = AUTH_BADCRED;
goto done;
}
Index: lib/librpcsec_gss/svc_rpcsec_gss.c
===================================================================
RCS file: /home/__orole/dev/cabinet/zeeNi/ai/freebsd/src/lib/librpcsec_gss/svc_rpcsec_gss.c,v
retrieving revision 1.4
diff -b -u -r1.4 svc_rpcsec_gss.c
--- lib/librpcsec_gss/svc_rpcsec_gss.c 3 Nov 2008 10:38:00 -0000 1.4
+++ lib/librpcsec_gss/svc_rpcsec_gss.c 5 Feb 2009 16:09:37 -0000
@@ -127,7 +127,7 @@
rpc_gss_ucred_t cl_ucred; /* unix-style credentials */
bool_t cl_done_callback; /* TRUE after call */
void *cl_cookie; /* user cookie from callback */
- gid_t cl_gid_storage[NGRPS];
+ gid_t cl_gid_storage[AUTH_UNIX_NGROUPS];
gss_OID cl_mech; /* mechanism */
gss_qop_t cl_qop; /* quality of protection */
u_int cl_seq; /* current sequence number */
@@ -578,7 +578,7 @@
getpwuid_r(uid, &pwd, buf, sizeof(buf), &pw);
if (pw) {
- int len = NGRPS;
+ int len = AUTH_UNIX_NGROUPS;
uc->uid = pw->pw_uid;
uc->gid = pw->pw_gid;
uc->gidlist = client->cl_gid_storage;
Index: sys/compat/svr4/svr4_misc.c
===================================================================
RCS file: /home/__orole/dev/cabinet/zeeNi/ai/freebsd/src/sys/compat/svr4/svr4_misc.c,v
retrieving revision 1.101
diff -b -u -r1.101 svr4_misc.c
--- sys/compat/svr4/svr4_misc.c 21 Apr 2008 21:24:08 -0000 1.101
+++ sys/compat/svr4/svr4_misc.c 14 Jan 2009 11:58:47 -0000
@@ -710,7 +710,12 @@
*retval = 0;
break;
case SVR4_CONFIG_NGROUPS:
- *retval = NGROUPS_MAX;
+ *retval = _NGROUPS_COMPAT;
+ /* XXX: this should pull the value
+ * from sysctl but i cannot find
+ * the definitions for the similar
+ * varaibles here (i.e. 'maxproc')
+ */
break;
case SVR4_CONFIG_CHILD_MAX:
*retval = maxproc;
Index: sys/fs/portalfs/portal.h
===================================================================
RCS file: /home/__orole/dev/cabinet/zeeNi/ai/freebsd/src/sys/fs/portalfs/portal.h,v
retrieving revision 1.10
diff -b -u -r1.10 portal.h
--- sys/fs/portalfs/portal.h 6 Jan 2005 18:10:40 -0000 1.10
+++ sys/fs/portalfs/portal.h 16 Jan 2009 23:44:50 -0000
@@ -43,7 +43,7 @@
int pcr_flag; /* File open mode */
uid_t pcr_uid; /* From ucred */
short pcr_ngroups; /* From ucred */
- gid_t pcr_groups[NGROUPS]; /* From ucred */
+ gid_t pcr_groups[_NGROUPS_COMPAT]; /* From ucred */
};
#ifdef _KERNEL
Index: sys/i386/ibcs2/ibcs2_misc.c
===================================================================
RCS file: /home/__orole/dev/cabinet/zeeNi/ai/freebsd/src/sys/i386/ibcs2/ibcs2_misc.c,v
retrieving revision 1.70
diff -b -u -r1.70 ibcs2_misc.c
--- sys/i386/ibcs2/ibcs2_misc.c 13 Jan 2008 14:44:07 -0000 1.70
+++ sys/i386/ibcs2/ibcs2_misc.c 14 Jan 2009 12:24:56 -0000
@@ -659,14 +659,14 @@
struct thread *td;
struct ibcs2_getgroups_args *uap;
{
- ibcs2_gid_t iset[NGROUPS_MAX];
- gid_t gp[NGROUPS_MAX];
+ ibcs2_gid_t iset[_NGROUPS_COMPAT];
+ gid_t gp[_NGROUPS_COMPAT];
u_int i, ngrp;
int error;
if (uap->gidsetsize < 0)
return (EINVAL);
- ngrp = MIN(uap->gidsetsize, NGROUPS_MAX);
+ ngrp = MIN(uap->gidsetsize, _NGROUPS_COMPAT);
error = kern_getgroups(td, &ngrp, gp);
if (error)
return (error);
@@ -685,11 +685,11 @@
struct thread *td;
struct ibcs2_setgroups_args *uap;
{
- ibcs2_gid_t iset[NGROUPS_MAX];
- gid_t gp[NGROUPS_MAX];
+ ibcs2_gid_t iset[_NGROUPS_COMPAT];
+ gid_t gp[_NGROUPS_COMPAT];
int error, i;
- if (uap->gidsetsize < 0 || uap->gidsetsize > NGROUPS_MAX)
+ if (uap->gidsetsize < 0 || uap->gidsetsize > _NGROUPS_COMPAT)
return (EINVAL);
if (uap->gidsetsize && uap->gidset) {
error = copyin(uap->gidset, iset, sizeof(ibcs2_gid_t) *
@@ -789,8 +789,13 @@
return 0;
case IBCS2_SC_NGROUPS_MAX:
- mib[1] = KERN_NGROUPS;
- break;
+ /* XXX: IBCS2 compat with group limits not known to
+ * me, so i'll just return a compatibile/safe limit
+ * for now */
+ PROC_LOCK(p) ;
+ td->td_retval[0] = _NGROUPS_COMPAT ;
+ PROC_UNLOCK(p) ;
+ return( 0 ) ;
case IBCS2_SC_OPEN_MAX:
PROC_LOCK(p);
Index: sys/kern/kern_mib.c
===================================================================
RCS file: /home/__orole/dev/cabinet/zeeNi/ai/freebsd/src/sys/kern/kern_mib.c,v
retrieving revision 1.93
diff -b -u -r1.93 kern_mib.c
--- sys/kern/kern_mib.c 28 Jan 2009 19:58:05 -0000 1.93
+++ sys/kern/kern_mib.c 4 Feb 2009 13:15:06 -0000
@@ -124,8 +124,8 @@
SYSCTL_INT(_kern, KERN_POSIX1, posix1version, CTLFLAG_RD,
0, _POSIX_VERSION, "Version of POSIX attempting to comply to");
-SYSCTL_INT(_kern, KERN_NGROUPS, ngroups, CTLFLAG_RD,
- 0, NGROUPS_MAX, "Maximum number of groups a user can belong to");
+SYSCTL_INT(_kern, KERN_NGROUPS, ngroups, CTLFLAG_RW,
+ 0, _NGROUPS_COMPAT, "Maximum number of groups allocated to a user");
SYSCTL_INT(_kern, KERN_JOB_CONTROL, job_control, CTLFLAG_RD,
0, 1, "Whether job control is available");
Index: sys/sys/param.h
===================================================================
RCS file: /home/__orole/dev/cabinet/zeeNi/ai/freebsd/src/sys/sys/param.h,v
retrieving revision 1.382
diff -b -u -r1.382 param.h
--- sys/sys/param.h 28 Jan 2009 17:57:16 -0000 1.382
+++ sys/sys/param.h 4 Feb 2009 14:11:55 -0000
@@ -57,7 +57,7 @@
* is created, otherwise 1.
*/
#undef __FreeBSD_version
-#define __FreeBSD_version 800062 /* Master, propagated to newvers */
+#define __FreeBSD_version 800060 /* Master, propagated to newvers */
#ifndef LOCORE
#include <sys/types.h>
@@ -77,7 +77,8 @@
#define MAXLOGNAME 17 /* max login name length (incl. NUL) */
#define MAXUPRC CHILD_MAX /* max simultaneous processes */
#define NCARGS ARG_MAX /* max bytes for an exec function */
-#define NGROUPS NGROUPS_MAX /* max number groups */
+#define NGROUPS _NGROUPS_COMPAT
+ /* depreciated check sysctl/sysconf for NGROUPS_MAX value instead */
#define NOFILE OPEN_MAX /* max open files per process */
#define NOGROUP 65535 /* marker for empty group set member */
#define MAXHOSTNAMELEN 256 /* max hostname size */
Index: sys/sys/syslimits.h
===================================================================
RCS file: /home/__orole/dev/cabinet/zeeNi/ai/freebsd/src/sys/sys/syslimits.h,v
retrieving revision 1.23
diff -b -u -r1.23 syslimits.h
--- sys/sys/syslimits.h 29 May 2007 15:14:46 -0000 1.23
+++ sys/sys/syslimits.h 3 Feb 2009 18:02:22 -0000
@@ -54,7 +54,6 @@
#define MAX_CANON 255 /* max bytes in term canon input line */
#define MAX_INPUT 255 /* max bytes in terminal input */
#define NAME_MAX 255 /* max bytes in a file name */
-#define NGROUPS_MAX 16 /* max supplemental group id's */
#ifndef OPEN_MAX
#define OPEN_MAX 64 /* max open files per process */
#endif
@@ -66,9 +65,35 @@
* We leave the following values undefined to force applications to either
* assume conservative values or call sysconf() to get the current value.
*
- * HOST_NAME_MAX
+ * HOST_NAME_MAX NGROUPS_MAX
*
* (We should do this for most of the values currently defined here,
* but many programs are not prepared to deal with this yet.)
*/
+/*
+ * here are some reference values in respect of the obsoleted
+ * NGROUPS_MAX value.
+ * nb: some apps appear to check NGROUPS_MAX as meaning that
+ * ... system has user groups (i.e. to #ifdef chunks of code).
+ * ... this is easy to change but maybe historically defined?
+ */
+#define _NGROUPS_RPC_MAX 16 /* reference only */
+ /* nb: this is the old system max, so named
+ * ... because it's limit appears to
+ * ... have been derived from a limitation
+ * ... in RPC (and thereby NFS), where it's
+ * ... the max number of groups we can exchange */
+#define _NGROUPS_COMPAT _NGROUPS_RPC_MAX /* reference only */
+ /* nb: although this is defined as equal to the rpc
+ * ... limit, i have defined it distintly so that
+ * ... we may distinguish (whilst updating) usage
+ * ... that is correctly explicit (i.e. should be 16)
+ * ... and usage that is only 16 because of an expected
+ * ... convention. hopefully we may remove these and
+ * ... define additional _NGROUPS_*_MAX for those defined
+ * ... uses. */
+#define _NGROUPS_SYS_MAX 65536 /* reference only */
+ /* nb: the idea's to have this extensible
+ * ... indefinately, this is what linux have and
+ * ... should more than cover immediate needs */
#endif
Index: usr.bin/catman/catman.c
===================================================================
RCS file: /home/__orole/dev/cabinet/zeeNi/ai/freebsd/src/usr.bin/catman/catman.c,v
retrieving revision 1.14
diff -b -u -r1.14 catman.c
--- usr.bin/catman/catman.c 5 Dec 2005 14:22:12 -0000 1.14
+++ usr.bin/catman/catman.c 8 Feb 2009 22:51:44 -0000
@@ -93,8 +93,9 @@
enum Ziptype {NONE, BZIP, GZIP};
static uid_t uid;
-static gid_t gids[NGROUPS_MAX];
+static gid_t *gids;
static int ngids;
+static int max_ngroups ;
static int starting_dir;
static char tmp_file[MAXPATHLEN];
struct stat test_st;
@@ -789,7 +790,15 @@
/* NOTREACHED */
}
}
- ngids = getgroups(NGROUPS_MAX, gids);
+/* allocate memory for group ids */
+#if _POSIX_VERSION > 199212
+ max_ngroups = sysconf( _SC_NGROUPS_MAX ) ;
+#elif defined(NGROUPS_MAX)
+ max_ngroups = NGROUPS_MAX ;
+#else
+ max_ngroups = _NGROUPS_COMPAT ;
+#endif
+ ngids = getgroups( max_ngroups, gids ) ;
if ((starting_dir = open(".", 0)) < 0) {
err(1, ".");
}
Index: usr.bin/newgrp/newgrp.c
===================================================================
RCS file: /home/__orole/dev/cabinet/zeeNi/ai/freebsd/src/usr.bin/newgrp/newgrp.c,v
retrieving revision 1.2
diff -b -u -r1.2 newgrp.c
--- usr.bin/newgrp/newgrp.c 30 Oct 2003 15:14:34 -0000 1.2
+++ usr.bin/newgrp/newgrp.c 9 Feb 2009 22:05:53 -0000
@@ -146,9 +146,10 @@
static void
addgroup(const char *grpname)
{
- gid_t grps[NGROUPS_MAX];
+ gid_t *grps;
long lgid;
- int dbmember, i, ngrps;
+ int dbmember, i, ngrps, max_ngroups ;
+ /* XXX: should 'max_ngroups' be a static const variable? */
gid_t egid;
struct group *grp;
char *ep, *pass;
@@ -185,9 +186,21 @@
}
}
- if ((ngrps = getgroups(NGROUPS_MAX, (gid_t *)grps)) < 0) {
+#if _POSIX_VERSION >= 199212
+ max_ngroups = sysconf( _SC_NGROUPS_MAX ) ;
+#elif defined(NGROUPS_MAX)
+ max_ngroups = NGROUPS_MAX ;
+#else
+ max_ngroups = _NGROUPS_COMPAT ;
+#endif
+ grps = (gid_t*)calloc( max_ngroups, sizeof(gid_t) ) ;
+ if( grps == NULL ) {
+ warn( "group set memory allocation" ) ;
+ return ;
+ }
+ if( (ngrps=getgroups(max_ngroups,(gid_t*)grps)) < 0 ) {
warn("getgroups");
- return;
+ goto error_free ;
}
/* Remove requested gid from supp. list if it exists. */
@@ -201,7 +214,7 @@
if (setgroups(ngrps, (const gid_t *)grps) < 0) {
PRIV_END;
warn("setgroups");
- return;
+ goto error_free ;
}
PRIV_END;
}
@@ -210,14 +223,14 @@
if (setgid(grp->gr_gid)) {
PRIV_END;
warn("setgid");
- return;
+ goto error_free ;
}
PRIV_END;
grps[0] = grp->gr_gid;
/* Add old effective gid to supp. list if it does not exist. */
if (egid != grp->gr_gid && !inarray(egid, grps, ngrps)) {
- if (ngrps == NGROUPS_MAX)
+ if( ngrps == max_ngroups )
warnx("too many groups");
else {
grps[ngrps++] = egid;
@@ -225,12 +238,15 @@
if (setgroups(ngrps, (const gid_t *)grps)) {
PRIV_END;
warn("setgroups");
- return;
+ goto error_free ;
}
PRIV_END;
}
}
+error_free:
+ free( grps ) ;
+ return ;
}
static int
Index: usr.sbin/chown/chown.c
===================================================================
RCS file: /home/__orole/dev/cabinet/zeeNi/ai/freebsd/src/usr.sbin/chown/chown.c,v
retrieving revision 1.29
diff -b -u -r1.29 chown.c
--- usr.sbin/chown/chown.c 7 Aug 2004 04:19:37 -0000 1.29
+++ usr.sbin/chown/chown.c 8 Feb 2009 16:22:31 -0000
@@ -269,7 +269,8 @@
{
static uid_t euid = -1;
static int ngroups = -1;
- gid_t groups[NGROUPS_MAX];
+ static int max_groups ;
+ gid_t *groups;
/* Check for chown without being root. */
if (errno != EPERM || (uid != (uid_t)-1 &&
@@ -279,16 +280,31 @@
}
/* Check group membership; kernel just returns EPERM. */
+#if _POSIX_VERSION >= 199212
+ max_groups = sysconf( _SC_NGROUPS_MAX ) ;
+#elif defined(NGROUPS_MAX)
+ max_groups = NGROUPS_MAX ;
+#else
+ max_groups = _NGROUPS_COMPAT ;
+#endif
+ groups = (gid_t*)calloc( max_groups, sizeof(gid_t) ) ;
+ if( groups == NULL ) {
+ warnx( "failed to allocate memory for group set" ) ;
+ goto exit_cleanup ;
+ }
if (gid != (gid_t)-1 && ngroups == -1 &&
euid == (uid_t)-1 && (euid = geteuid()) != 0) {
- ngroups = getgroups(NGROUPS_MAX, groups);
+ ngroups = getgroups( max_groups, groups ) ;
while (--ngroups >= 0 && gid != groups[ngroups]);
if (ngroups < 0) {
warnx("you are not a member of group %s", gname);
- return;
+ goto exit_cleanup ;
}
}
warn("%s", file);
+exit_cleanup:
+ free( groups ) ;
+ return ;
}
void
Index: usr.sbin/chroot/chroot.c
===================================================================
RCS file: /home/__orole/dev/cabinet/zeeNi/ai/freebsd/src/usr.sbin/chroot/chroot.c,v
retrieving revision 1.11
diff -b -u -r1.11 chroot.c
--- usr.sbin/chroot/chroot.c 7 Aug 2004 04:19:37 -0000 1.11
+++ usr.sbin/chroot/chroot.c 5 Feb 2009 23:29:48 -0000
@@ -59,6 +59,7 @@
char *user; /* user to switch to before running program */
char *group; /* group to switch to ... */
char *grouplist; /* group list to switch to ... */
+int max_ngroups; /* max number of groups allowable */
int
main(argc, argv)
@@ -69,12 +70,25 @@
struct passwd *pw;
char *endp, *p;
const char *shell;
- gid_t gid, gidlist[NGROUPS_MAX];
+ gid_t gid, *gidlist ;
uid_t uid;
- int ch, gids;
+ int ch, gids ;
+/* set some defaults */
gid = 0;
uid = 0;
+ user = NULL ;
+ group = NULL ;
+ grouplist = NULL ;
+#if _POSIX_VERSION >= 199212
+ max_ngroups = sysconf( _SC_NGROUPS_MAX ) ;
+#elif defined(NGROUPS_MAX)
+ max_ngroups = NGROUPS_MAX ;
+#else
+ max_ngroups = _NGROUPS_COMPAT ;
+#endif
+
+/* process command line options */
while ((ch = getopt(argc, argv, "G:g:u:")) != -1) {
switch(ch) {
case 'u':
@@ -103,9 +117,12 @@
if (argc < 1)
usage();
+/* if a group argument was passed then process it */
if (group != NULL) {
+ /* if the first char's a digit then assume it's a gid ... */
if (isdigit((unsigned char)*group)) {
gid = (gid_t)strtoul(group, &endp, 0);
+ /* ... and back out that assumption if it proves wrong */
if (*endp != '\0')
goto getgroup;
} else {
@@ -117,8 +134,15 @@
}
}
- for (gids = 0;
- (p = strsep(&grouplist, ",")) != NULL && gids < NGROUPS_MAX; ) {
+/* process command line group list */
+ if( grouplist != NULL ) {
+ gidlist = (gid_t*)calloc( max_ngroups, sizeof(gid_t) ) ;
+ if( gidlist == NULL )
+ errx( 1, "inadquate memory for group list" ) ;
+ for( gids = 0 ;
+ gids < max_ngroups &&
+ (p=strsep(&grouplist,",")) != NULL ; )
+ {
if (*p == '\0')
continue;
@@ -135,9 +159,11 @@
}
gids++;
}
- if (p != NULL && gids == NGROUPS_MAX)
+ if( p != NULL && gids == max_ngroups )
errx(1, "too many supplementary groups provided");
+ }
+/* set user from command line option, if supplied */
if (user != NULL) {
if (isdigit((unsigned char)*user)) {
uid = (uid_t)strtoul(user, &endp, 0);
@@ -152,9 +178,11 @@
}
}
+/* change root */
if (chdir(argv[0]) == -1 || chroot(".") == -1)
err(1, "%s", argv[0]);
+/* set credentials */
if (gids && setgroups(gids, gidlist) == -1)
err(1, "setgroups");
if (group && setgid(gid) == -1)
@@ -162,11 +190,14 @@
if (user && setuid(uid) == -1)
err(1, "setuid");
+/* exec the remaining arguments as the chroot'd command ... */
if (argv[1]) {
execvp(argv[1], &argv[1]);
err(1, "%s", argv[1]);
+ /* NOTREACHED */
}
+/* ... or execute the default system shell */
if (!(shell = getenv("SHELL")))
shell = _PATH_BSHELL;
execlp(shell, shell, "-i", (char *)NULL);
Index: usr.sbin/gssd/gssd.c
===================================================================
RCS file: /home/__orole/dev/cabinet/zeeNi/ai/freebsd/src/usr.sbin/gssd/gssd.c,v
retrieving revision 1.1
diff -b -u -r1.1 gssd.c
--- usr.sbin/gssd/gssd.c 3 Nov 2008 10:38:00 -0000 1.1
+++ usr.sbin/gssd/gssd.c 5 Feb 2009 16:16:37 -0000
@@ -464,8 +464,8 @@
result->uid = uid;
getpwuid_r(uid, &pwd, buf, sizeof(buf), &pw);
if (pw) {
- int len = NGRPS;
- int groups[NGRPS];
+ int len = AUTH_UNIX_NGROUPS ;
+ int groups[AUTH_UNIX_NGROUPS] ;
result->gid = pw->pw_gid;
getgrouplist(pw->pw_name, pw->pw_gid,
groups, &len);
Index: usr.sbin/mount_portalfs/cred.c
===================================================================
RCS file: /home/__orole/dev/cabinet/zeeNi/ai/freebsd/src/usr.sbin/mount_portalfs/cred.c,v
retrieving revision 1.1
diff -b -u -r1.1 cred.c
--- usr.sbin/mount_portalfs/cred.c 11 Mar 2005 08:39:58 -0000 1.1
+++ usr.sbin/mount_portalfs/cred.c 16 Jan 2009 23:49:36 -0000
@@ -46,7 +46,7 @@
set_user_credentials(struct portal_cred *user, struct portal_cred *save)
{
save->pcr_uid = geteuid();
- if ((save->pcr_ngroups = getgroups(NGROUPS_MAX, save->pcr_groups)) < 0)
+ if( (save->pcr_ngroups=getgroups(_NGROUPS_COMPAT,save->pcr_groups)) < 0 )
return (-1);
if (setgroups(user->pcr_ngroups, user->pcr_groups) < 0)
return (-1);
Index: usr.sbin/pppd/options.c
===================================================================
RCS file: /home/__orole/dev/cabinet/zeeNi/ai/freebsd/src/usr.sbin/pppd/options.c,v
retrieving revision 1.26
diff -b -u -r1.26 options.c
--- usr.sbin/pppd/options.c 7 Nov 2007 10:53:38 -0000 1.26
+++ usr.sbin/pppd/options.c 10 Feb 2009 09:11:47 -0000
@@ -72,10 +72,6 @@
char *strdup(char *);
#endif
-#ifndef GIDSET_TYPE
-#define GIDSET_TYPE gid_t
-#endif
-
/*
* Option variables and default values.
*/
@@ -779,23 +775,64 @@
int fd;
{
uid_t uid;
- int ngroups, i;
+ int ngroups, max_ngroups, i;
struct stat sbuf;
- GIDSET_TYPE groups[NGROUPS_MAX];
+ gid_t *groups;
+/* get the uid */
uid = getuid();
+/* ... and return true if root */
+/* XXX: needs credential check */
if (uid == 0)
return 1;
+
+/* if we're not root, get some info about the file */
if (fstat(fd, &sbuf) != 0)
return 0;
+
+/* test for owner match with current process */
if (sbuf.st_uid == uid)
return sbuf.st_mode & S_IRUSR;
+/* ... and a group match */
if (sbuf.st_gid == getgid())
return sbuf.st_mode & S_IRGRP;
- ngroups = getgroups(NGROUPS_MAX, groups);
- for (i = 0; i < ngroups; ++i)
- if (sbuf.st_gid == groups[i])
- return sbuf.st_mode & S_IRGRP;
+
+/* if we've still no luck then check the group list for permission match */
+#if _POSIX_VERSION >= 199212
+ max_ngroups = sysconf( _SC_NGROUPS_MAX ) ;
+#elif defined(NGROUPS_MAX)
+ max_ngroups = NGROUPS_MAX ;
+#else
+ max_ngroups = _NGROUPS_COMPAT ;
+#endif
+ groups = (gid_t*) calloc( max_ngroups, sizeof(gid_t) ) ;
+ if( groups == NULL ) {
+ /* if we cannot check groups correctly then assume 'fd' is unreadable
+ * XXX: this may be false as the converse is more likely.
+ * i.e. it would be failed readable on available groups
+ * and granted on full list, however, we just can't be
+ * psychic and i'm not about to code some idiotic loop that tries
+ * to get 'some' memory for partial testing. probably a better
+ * recourse would be to simply die here but that seems severe
+ * for a 'readable' test.
+ * NB: we don't need a 'full' allocation of memory to test the
+ * group list, only to store it. one idea would be to do this in
+ * 'blocks'
+ */
+ option_error( 1, "unable to allocate memory for group list" ) ;
+ return( 0 ) ;
+ }
+/* get groups */
+ ngroups = getgroups( max_ngroups, groups ) ;
+/* ... and test the group permission if matching */
+ for( i = 0 ; i < ngroups ; ++i ) {
+ if (sbuf.st_gid == groups[i]) {
+ free( (void*)groups) ;
+ return( sbuf.st_mode & S_IRGRP ) ;
+ }
+ }
+/* otherwise return other permissions match */
+ free( (void*)groups ) ;
return sbuf.st_mode & S_IROTH;
}
Index: usr.sbin/rpc.lockd/kern.c
===================================================================
RCS file: /home/__orole/dev/cabinet/zeeNi/ai/freebsd/src/usr.sbin/rpc.lockd/kern.c,v
retrieving revision 1.21
diff -b -u -r1.21 kern.c
--- usr.sbin/rpc.lockd/kern.c 17 Aug 2006 05:55:20 -0000 1.21
+++ usr.sbin/rpc.lockd/kern.c 5 Feb 2009 16:22:17 -0000
@@ -239,15 +239,15 @@
int ngroups;
ngroups = xucred->cr_ngroups - 1;
- if (ngroups > NGRPS)
- ngroups = NGRPS;
- if (cl->cl_auth != NULL)
- cl->cl_auth->ah_ops->ah_destroy(cl->cl_auth);
- cl->cl_auth = authunix_create(hostname,
+ if( ngroups > AUTH_UNIX_NGROUPS )
+ ngroups = AUTH_UNIX_NGROUPS ;
+ if( cl->cl_auth != NULL )
+ cl->cl_auth->ah_ops->ah_destroy( cl->cl_auth ) ;
+ cl->cl_auth = authunix_create( hostname,
xucred->cr_uid,
xucred->cr_groups[0],
ngroups,
- &xucred->cr_groups[1]);
+ &xucred->cr_groups[1] ) ;
}
More information about the freebsd-hackers
mailing list