* nis/nss_compat/compat-initgroups.c (getgrent_next_nss,
	_nss_compat_initgroups_dyn): Fall back to malloc/free for
	large group memberships.
This commit is contained in:
Jeff Law 2012-03-29 09:56:27 -06:00
parent 88d85d4f00
commit 984a42374c
3 changed files with 69 additions and 18 deletions

View File

@ -1,3 +1,10 @@
2012-03-28 Siddhesh Poyarekar <siddhesh@redhat.com>
[BZ #13761]
* nis/nss_compat/compat-initgroups.c (getgrent_next_nss,
_nss_compat_initgroups_dyn): Fall back to malloc/free
for large group memberships.
2012-03-28 David S. Miller <davem@davemloft.net>
* sysdeps/sparc/sparc32/memcpy.S: Implement mempcpy using a stub

6
NEWS
View File

@ -16,9 +16,9 @@ Version 2.16
11494, 12047, 13058, 13525, 13526, 13527, 13528, 13529, 13530, 13531,
13532, 13533, 13547, 13551, 13552, 13553, 13555, 13559, 13566, 13583,
13618, 13637, 13656, 13658, 13673, 13695, 13704, 13706, 13726, 13738,
13760, 13786, 13792, 13806, 13824, 13840, 13841, 13844, 13846, 13851,
13852, 13854, 13871, 13879, 13883, 13892, 13910, 13911, 13912, 13913,
13915, 13916, 13917, 13918, 13919, 13920, 13921
13760, 13761, 13786, 13792, 13806, 13824, 13840, 13841, 13844, 13846,
13851, 13852, 13854, 13871, 13879, 13883, 13892, 13910, 13911, 13912,
13913, 13915, 13916, 13917, 13918, 13919, 13920, 13921
* ISO C11 support:

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1998-2004,2006,2007,2009,2010 Free Software Foundation, Inc.
/* Copyright (C) 1998-2004,2006,2007,2009,2010,2012 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@suse.de>, 1998.
@ -296,6 +296,8 @@ getgrent_next_nss (ent_t *ent, char *buffer, size_t buflen, const char *user,
if (nss_initgroups_dyn (user, group, &mystart, &mysize, &mygroups,
limit, errnop) == NSS_STATUS_SUCCESS)
{
status = NSS_STATUS_NOTFOUND;
/* If there is no blacklist we can trust the underlying
initgroups implementation. */
if (ent->blacklist.current <= 1)
@ -308,6 +310,7 @@ getgrent_next_nss (ent_t *ent, char *buffer, size_t buflen, const char *user,
overwrite the pointer with one to a bigger buffer. */
char *tmpbuf = buffer;
size_t tmplen = buflen;
bool use_malloc = false;
for (int i = 0; i < mystart; i++)
{
@ -315,21 +318,36 @@ getgrent_next_nss (ent_t *ent, char *buffer, size_t buflen, const char *user,
tmpbuf, tmplen, errnop))
== NSS_STATUS_TRYAGAIN
&& *errnop == ERANGE)
if (tmpbuf == buffer)
{
tmplen *= 2;
tmpbuf = __alloca (tmplen);
}
else
tmpbuf = extend_alloca (tmpbuf, tmplen, 2 * tmplen);
{
if (__libc_use_alloca (tmplen * 2))
{
if (tmpbuf == buffer)
{
tmplen *= 2;
tmpbuf = __alloca (tmplen);
}
else
tmpbuf = extend_alloca (tmpbuf, tmplen, tmplen * 2);
}
else
{
tmplen *= 2;
char *newbuf = realloc (use_malloc ? tmpbuf : NULL, tmplen);
if (newbuf == NULL)
{
status = NSS_STATUS_TRYAGAIN;
goto done;
}
use_malloc = true;
tmpbuf = newbuf;
}
}
if (__builtin_expect (status != NSS_STATUS_NOTFOUND, 1))
{
if (__builtin_expect (status != NSS_STATUS_SUCCESS, 0))
{
free (mygroups);
return status;
}
goto done;
if (!in_blacklist (grpbuf.gr_name,
strlen (grpbuf.gr_name), ent)
@ -347,11 +365,17 @@ getgrent_next_nss (ent_t *ent, char *buffer, size_t buflen, const char *user,
}
}
}
status = NSS_STATUS_NOTFOUND;
done:
if (use_malloc)
free (tmpbuf);
}
free (mygroups);
return NSS_STATUS_NOTFOUND;
return status;
}
free (mygroups);
@ -508,6 +532,7 @@ _nss_compat_initgroups_dyn (const char *user, gid_t group, long int *start,
char *tmpbuf;
enum nss_status status;
ent_t intern = { true, false, false, NULL, {NULL, 0, 0} };
bool use_malloc = false;
status = internal_setgrent (&intern);
if (status != NSS_STATUS_SUCCESS)
@ -521,13 +546,32 @@ _nss_compat_initgroups_dyn (const char *user, gid_t group, long int *start,
user, group, start, size,
groupsp, limit, errnop))
== NSS_STATUS_TRYAGAIN && *errnop == ERANGE)
tmpbuf = extend_alloca (tmpbuf, buflen, 2 * buflen);
if (__libc_use_alloca (buflen * 2))
tmpbuf = extend_alloca (tmpbuf, buflen, 2 * buflen);
else
{
buflen *= 2;
char *newbuf = realloc (use_malloc ? tmpbuf : NULL, buflen);
if (newbuf == NULL)
{
status = NSS_STATUS_TRYAGAIN;
goto done;
}
use_malloc = true;
tmpbuf = newbuf;
}
}
while (status == NSS_STATUS_SUCCESS);
status = NSS_STATUS_SUCCESS;
done:
if (use_malloc)
free (tmpbuf);
internal_endgrent (&intern);
return NSS_STATUS_SUCCESS;
return status;
}