mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-24 22:10:13 +00:00
Update.
* sunrpc/svcauth_des.c (authdes_getucred): Removed fixed limit on number of groups in the cache. Relax the disconnect between the interface of authdes_getucred and netname2user a bit. * sunrpc/auth_unix.c (authunix_create_default): Don't allocate huge arrays on the stack.
This commit is contained in:
parent
5db7adc49d
commit
773640b4f5
@ -1,5 +1,11 @@
|
|||||||
2004-02-26 Ulrich Drepper <drepper@redhat.com>
|
2004-02-26 Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
|
* sunrpc/svcauth_des.c (authdes_getucred): Removed fixed limit on
|
||||||
|
number of groups in the cache. Relax the disconnect between the
|
||||||
|
interface of authdes_getucred and netname2user a bit.
|
||||||
|
* sunrpc/auth_unix.c (authunix_create_default): Don't allocate
|
||||||
|
huge arrays on the stack.
|
||||||
|
|
||||||
* sysdeps/unix/sysv/linux/sysconf.c (__sysconf): Use the official
|
* sysdeps/unix/sysv/linux/sysconf.c (__sysconf): Use the official
|
||||||
not cancelable interfaces.
|
not cancelable interfaces.
|
||||||
|
|
||||||
|
@ -38,7 +38,9 @@
|
|||||||
* for the credentials.
|
* for the credentials.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -165,25 +167,61 @@ INTDEF (authunix_create)
|
|||||||
AUTH *
|
AUTH *
|
||||||
authunix_create_default (void)
|
authunix_create_default (void)
|
||||||
{
|
{
|
||||||
int len;
|
|
||||||
char machname[MAX_MACHINE_NAME + 1];
|
char machname[MAX_MACHINE_NAME + 1];
|
||||||
uid_t uid;
|
|
||||||
gid_t gid;
|
|
||||||
int max_nr_groups = __sysconf (_SC_NGROUPS_MAX);
|
|
||||||
gid_t gids[max_nr_groups];
|
|
||||||
|
|
||||||
if (__gethostname (machname, MAX_MACHINE_NAME) == -1)
|
if (__gethostname (machname, MAX_MACHINE_NAME) == -1)
|
||||||
abort ();
|
abort ();
|
||||||
machname[MAX_MACHINE_NAME] = 0;
|
machname[MAX_MACHINE_NAME] = 0;
|
||||||
uid = __geteuid ();
|
uid_t uid = __geteuid ();
|
||||||
gid = __getegid ();
|
gid_t gid = __getegid ();
|
||||||
|
|
||||||
|
int max_nr_groups;
|
||||||
|
/* When we have to try a second time, do not use alloca() again. We
|
||||||
|
might have reached the stack limit already. */
|
||||||
|
bool retry = false;
|
||||||
|
again:
|
||||||
|
/* Ask the kernel how many groups there are exactly. Note that we
|
||||||
|
might have to redo all this if the number of groups has changed
|
||||||
|
between the two calls. */
|
||||||
|
max_nr_groups = __getgroups (0, NULL);
|
||||||
|
|
||||||
|
/* Just some random reasonable stack limit. */
|
||||||
|
#define ALLOCA_LIMIT (1024 / sizeof (gid_t))
|
||||||
|
gid_t *gids = NULL;
|
||||||
|
if (max_nr_groups < ALLOCA_LIMIT && ! retry)
|
||||||
|
gids = (gid_t *) alloca (max_nr_groups * sizeof (gid_t));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gids = (gid_t *) malloc (max_nr_groups * sizeof (gid_t));
|
||||||
|
if (gids == NULL)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int len = __getgroups (max_nr_groups, gids);
|
||||||
|
if (len == -1)
|
||||||
|
{
|
||||||
|
if (errno == EINVAL)
|
||||||
|
{
|
||||||
|
/* New groups added in the meantime. Try again. */
|
||||||
|
if (max_nr_groups >= ALLOCA_LIMIT || retry)
|
||||||
|
free (gids);
|
||||||
|
retry = true;
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
|
/* No other error can happen. */
|
||||||
|
abort ();
|
||||||
|
}
|
||||||
|
|
||||||
if ((len = __getgroups (max_nr_groups, gids)) < 0)
|
|
||||||
abort ();
|
|
||||||
/* This braindamaged Sun code forces us here to truncate the
|
/* This braindamaged Sun code forces us here to truncate the
|
||||||
list of groups to NGRPS members since the code in
|
list of groups to NGRPS members since the code in
|
||||||
authuxprot.c transforms a fixed array. Grrr. */
|
authuxprot.c transforms a fixed array. Grrr. */
|
||||||
return INTUSE(authunix_create) (machname, uid, gid, MIN (NGRPS, len), gids);
|
AUTH *result = INTUSE(authunix_create) (machname, uid, gid, MIN (NGRPS, len),
|
||||||
|
gids);
|
||||||
|
|
||||||
|
if (max_nr_groups >= ALLOCA_LIMIT || retry)
|
||||||
|
free (gids);
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
INTDEF (authunix_create_default)
|
INTDEF (authunix_create_default)
|
||||||
|
|
||||||
|
@ -43,6 +43,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
@ -487,8 +488,9 @@ struct bsdcred
|
|||||||
{
|
{
|
||||||
uid_t uid; /* cached uid */
|
uid_t uid; /* cached uid */
|
||||||
gid_t gid; /* cached gid */
|
gid_t gid; /* cached gid */
|
||||||
short grouplen; /* length of cached groups */
|
int grouplen; /* length of cached groups */
|
||||||
gid_t groups[NGROUPS]; /* cached groups */
|
int grouplen_max; /* length of allocated cached groups */
|
||||||
|
gid_t groups[0]; /* cached groups */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -515,13 +517,7 @@ authdes_getucred (const struct authdes_cred *adc, uid_t * uid, gid_t * gid,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
cred = (struct bsdcred *) authdes_cache[sid].localcred;
|
cred = (struct bsdcred *) authdes_cache[sid].localcred;
|
||||||
if (cred == NULL)
|
if (cred == NULL || cred->grouplen == INVALID)
|
||||||
{
|
|
||||||
cred = (struct bsdcred *) mem_alloc (sizeof (struct bsdcred));
|
|
||||||
authdes_cache[sid].localcred = (char *) cred;
|
|
||||||
cred->grouplen = INVALID;
|
|
||||||
}
|
|
||||||
if (cred->grouplen == INVALID)
|
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* not in cache: lookup
|
* not in cache: lookup
|
||||||
@ -530,15 +526,43 @@ authdes_getucred (const struct authdes_cred *adc, uid_t * uid, gid_t * gid,
|
|||||||
&i_grouplen, groups))
|
&i_grouplen, groups))
|
||||||
{
|
{
|
||||||
debug ("unknown netname");
|
debug ("unknown netname");
|
||||||
cred->grouplen = UNKNOWN; /* mark as lookup up, but not found */
|
if (cred != NULL)
|
||||||
|
cred->grouplen = UNKNOWN; /* mark as lookup up, but not found */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cred != NULL && cred->grouplen_max < i_grouplen)
|
||||||
|
{
|
||||||
|
/* We already have an allocated data structure. But it is
|
||||||
|
too small. */
|
||||||
|
free (cred);
|
||||||
|
authdes_cache[sid].localcred = NULL;
|
||||||
|
cred = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cred == NULL)
|
||||||
|
{
|
||||||
|
/* We should allocate room for at least NGROUPS groups. */
|
||||||
|
int ngroups_max = MAX (i_grouplen, NGROUPS);
|
||||||
|
|
||||||
|
cred = (struct bsdcred *) mem_alloc (sizeof (struct bsdcred)
|
||||||
|
+ ngroups_max * sizeof (gid_t));
|
||||||
|
if (cred == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
authdes_cache[sid].localcred = (char *) cred;
|
||||||
|
cred->grouplen = INVALID;
|
||||||
|
cred->grouplen_max = ngroups_max;
|
||||||
|
}
|
||||||
|
|
||||||
debug ("missed ucred cache");
|
debug ("missed ucred cache");
|
||||||
*uid = cred->uid = i_uid;
|
*uid = cred->uid = i_uid;
|
||||||
*gid = cred->gid = i_gid;
|
*gid = cred->gid = i_gid;
|
||||||
*grouplen = cred->grouplen = i_grouplen;
|
cred->grouplen = i_grouplen;
|
||||||
for (i = i_grouplen - 1; i >= 0; --i)
|
for (i = i_grouplen - 1; i >= 0; --i)
|
||||||
cred->groups[i] = groups[i]; /* int to short */
|
cred->groups[i] = groups[i];
|
||||||
|
/* Make sure no too large values are reported. */
|
||||||
|
*grouplen = MIN (SHRT_MAX, i_grouplen);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else if (cred->grouplen == UNKNOWN)
|
else if (cred->grouplen == UNKNOWN)
|
||||||
@ -554,9 +578,13 @@ authdes_getucred (const struct authdes_cred *adc, uid_t * uid, gid_t * gid,
|
|||||||
*/
|
*/
|
||||||
*uid = cred->uid;
|
*uid = cred->uid;
|
||||||
*gid = cred->gid;
|
*gid = cred->gid;
|
||||||
*grouplen = cred->grouplen;
|
|
||||||
for (i = cred->grouplen - 1; i >= 0; --i)
|
/* Another stupidity in the interface: *grouplen is of type short.
|
||||||
groups[i] = cred->groups[i]; /* short to int */
|
So we might have to cut the information passed up short. */
|
||||||
|
int grouplen_copy = MIN (SHRT_MAX, cred->grouplen);
|
||||||
|
*grouplen = grouplen_copy;
|
||||||
|
for (i = grouplen_copy - 1; i >= 0; --i)
|
||||||
|
groups[i] = cred->groups[i];
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user