mirror of git://sourceware.org/git/glibc.git
getgrent_next_nss (compat-initgroups): Remove alloca fallback [BZ #18023]
If the caller-supplied buffer is not large enough, fall back directly malloc. The previous __libc_use_alloca check was incorrect because it did not take into account that extend_alloca may fail to merge allocations, so it would underestimate the stack space being used by roughly a factor of two.
This commit is contained in:
parent
6b7b2abac7
commit
90d9d9ce2f
|
@ -1,3 +1,9 @@
|
||||||
|
2018-06-25 Florian Weimer <fweimer@redhat.com>
|
||||||
|
|
||||||
|
[BZ #18023]
|
||||||
|
* nss/nss_compat/compat-initgroups.c (getgrent_next_nss): Fall
|
||||||
|
back to malloc directly, without stack allocations.
|
||||||
|
|
||||||
2018-06-25 Florian Weimer <fweimer@redhat.com>
|
2018-06-25 Florian Weimer <fweimer@redhat.com>
|
||||||
|
|
||||||
[BZ #18023]
|
[BZ #18023]
|
||||||
|
|
|
@ -261,7 +261,6 @@ getgrent_next_nss (ent_t *ent, char *buffer, size_t buflen, const char *user,
|
||||||
overwrite the pointer with one to a bigger buffer. */
|
overwrite the pointer with one to a bigger buffer. */
|
||||||
char *tmpbuf = buffer;
|
char *tmpbuf = buffer;
|
||||||
size_t tmplen = buflen;
|
size_t tmplen = buflen;
|
||||||
bool use_malloc = false;
|
|
||||||
|
|
||||||
for (int i = 0; i < mystart; i++)
|
for (int i = 0; i < mystart; i++)
|
||||||
{
|
{
|
||||||
|
@ -270,29 +269,26 @@ getgrent_next_nss (ent_t *ent, char *buffer, size_t buflen, const char *user,
|
||||||
== NSS_STATUS_TRYAGAIN
|
== NSS_STATUS_TRYAGAIN
|
||||||
&& *errnop == ERANGE)
|
&& *errnop == ERANGE)
|
||||||
{
|
{
|
||||||
if (__libc_use_alloca (tmplen * 2))
|
/* Check for overflow. */
|
||||||
{
|
if (__glibc_unlikely (tmplen * 2 < tmplen))
|
||||||
if (tmpbuf == buffer)
|
{
|
||||||
{
|
__set_errno (ENOMEM);
|
||||||
tmplen *= 2;
|
status = NSS_STATUS_TRYAGAIN;
|
||||||
tmpbuf = __alloca (tmplen);
|
goto done;
|
||||||
}
|
}
|
||||||
else
|
/* Increase the size. Make sure that we retry
|
||||||
tmpbuf = extend_alloca (tmpbuf, tmplen, tmplen * 2);
|
with a reasonable size. */
|
||||||
}
|
tmplen *= 2;
|
||||||
else
|
if (tmplen < 1024)
|
||||||
{
|
tmplen = 1024;
|
||||||
tmplen *= 2;
|
if (tmpbuf != buffer)
|
||||||
char *newbuf = realloc (use_malloc ? tmpbuf : NULL, tmplen);
|
free (tmpbuf);
|
||||||
|
tmpbuf = malloc (tmplen);
|
||||||
if (newbuf == NULL)
|
if (__glibc_unlikely (tmpbuf == NULL))
|
||||||
{
|
{
|
||||||
status = NSS_STATUS_TRYAGAIN;
|
status = NSS_STATUS_TRYAGAIN;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
use_malloc = true;
|
|
||||||
tmpbuf = newbuf;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (__builtin_expect (status != NSS_STATUS_NOTFOUND, 1))
|
if (__builtin_expect (status != NSS_STATUS_NOTFOUND, 1))
|
||||||
|
@ -320,7 +316,7 @@ getgrent_next_nss (ent_t *ent, char *buffer, size_t buflen, const char *user,
|
||||||
status = NSS_STATUS_NOTFOUND;
|
status = NSS_STATUS_NOTFOUND;
|
||||||
|
|
||||||
done:
|
done:
|
||||||
if (use_malloc)
|
if (tmpbuf != buffer)
|
||||||
free (tmpbuf);
|
free (tmpbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue