mirror of
git://sourceware.org/git/glibc.git
synced 2024-12-15 04:20:28 +08:00
nscd: Switch to struct scratch_buffer in adhstaiX [BZ #18023]
The pre-allocation of the three scratch buffers increased the initial stack size somewhat, but if retries are needed, the previous version used more stack space if extend_alloca could not merge allocations. Lack of alloca accounting also means could be problematic with extremely large NSS responses, too. [BZ #18023] * nscd/aicache.c (addhstaiX): Use struct scratch_buffer instead of extend_alloca.
This commit is contained in:
parent
2f9f0d182e
commit
6b7b2abac7
@ -1,3 +1,9 @@
|
|||||||
|
2018-06-25 Florian Weimer <fweimer@redhat.com>
|
||||||
|
|
||||||
|
[BZ #18023]
|
||||||
|
* nscd/aicache.c (addhstaiX): Use struct scratch_buffer instead
|
||||||
|
of extend_alloca.
|
||||||
|
|
||||||
2018-06-25 Florian Weimer <fweimer@redhat.com>
|
2018-06-25 Florian Weimer <fweimer@redhat.com>
|
||||||
|
|
||||||
[BZ #18023]
|
[BZ #18023]
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include <resolv/resolv-internal.h>
|
#include <resolv/resolv-internal.h>
|
||||||
#include <resolv/resolv_context.h>
|
#include <resolv/resolv_context.h>
|
||||||
#include <resolv/res_use_inet6.h>
|
#include <resolv/res_use_inet6.h>
|
||||||
|
#include <scratch_buffer.h>
|
||||||
|
|
||||||
#include "dbg_log.h"
|
#include "dbg_log.h"
|
||||||
#include "nscd.h"
|
#include "nscd.h"
|
||||||
@ -108,10 +109,13 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req,
|
|||||||
if (ctx == NULL)
|
if (ctx == NULL)
|
||||||
no_more = 1;
|
no_more = 1;
|
||||||
|
|
||||||
size_t tmpbuf6len = 1024;
|
struct scratch_buffer tmpbuf6;
|
||||||
char *tmpbuf6 = alloca (tmpbuf6len);
|
scratch_buffer_init (&tmpbuf6);
|
||||||
size_t tmpbuf4len = 0;
|
struct scratch_buffer tmpbuf4;
|
||||||
char *tmpbuf4 = NULL;
|
scratch_buffer_init (&tmpbuf4);
|
||||||
|
struct scratch_buffer canonbuf;
|
||||||
|
scratch_buffer_init (&canonbuf);
|
||||||
|
|
||||||
int32_t ttl = INT32_MAX;
|
int32_t ttl = INT32_MAX;
|
||||||
ssize_t total = 0;
|
ssize_t total = 0;
|
||||||
char *key_copy = NULL;
|
char *key_copy = NULL;
|
||||||
@ -124,6 +128,7 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req,
|
|||||||
int status[2] = { NSS_STATUS_UNAVAIL, NSS_STATUS_UNAVAIL };
|
int status[2] = { NSS_STATUS_UNAVAIL, NSS_STATUS_UNAVAIL };
|
||||||
int naddrs = 0;
|
int naddrs = 0;
|
||||||
size_t addrslen = 0;
|
size_t addrslen = 0;
|
||||||
|
|
||||||
char *canon = NULL;
|
char *canon = NULL;
|
||||||
size_t canonlen;
|
size_t canonlen;
|
||||||
|
|
||||||
@ -138,12 +143,17 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req,
|
|||||||
at = &atmem;
|
at = &atmem;
|
||||||
rc6 = 0;
|
rc6 = 0;
|
||||||
herrno = 0;
|
herrno = 0;
|
||||||
status[1] = DL_CALL_FCT (fct4, (key, &at, tmpbuf6, tmpbuf6len,
|
status[1] = DL_CALL_FCT (fct4, (key, &at,
|
||||||
|
tmpbuf6.data, tmpbuf6.length,
|
||||||
&rc6, &herrno, &ttl));
|
&rc6, &herrno, &ttl));
|
||||||
if (rc6 != ERANGE || (herrno != NETDB_INTERNAL
|
if (rc6 != ERANGE || (herrno != NETDB_INTERNAL
|
||||||
&& herrno != TRY_AGAIN))
|
&& herrno != TRY_AGAIN))
|
||||||
break;
|
break;
|
||||||
tmpbuf6 = extend_alloca (tmpbuf6, tmpbuf6len, 2 * tmpbuf6len);
|
if (!scratch_buffer_grow (&tmpbuf6))
|
||||||
|
{
|
||||||
|
rc6 = ENOMEM;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rc6 != 0 && herrno == NETDB_INTERNAL)
|
if (rc6 != 0 && herrno == NETDB_INTERNAL)
|
||||||
@ -221,41 +231,38 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req,
|
|||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
rc6 = 0;
|
rc6 = 0;
|
||||||
status[0] = DL_CALL_FCT (fct, (key, AF_INET6, &th[0], tmpbuf6,
|
status[0] = DL_CALL_FCT (fct, (key, AF_INET6, &th[0],
|
||||||
tmpbuf6len, &rc6, &herrno, &ttl,
|
tmpbuf6.data, tmpbuf6.length,
|
||||||
|
&rc6, &herrno, &ttl,
|
||||||
&canon));
|
&canon));
|
||||||
if (rc6 != ERANGE || herrno != NETDB_INTERNAL)
|
if (rc6 != ERANGE || herrno != NETDB_INTERNAL)
|
||||||
break;
|
break;
|
||||||
tmpbuf6 = extend_alloca (tmpbuf6, tmpbuf6len, 2 * tmpbuf6len);
|
if (!scratch_buffer_grow (&tmpbuf6))
|
||||||
|
{
|
||||||
|
rc6 = ENOMEM;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rc6 != 0 && herrno == NETDB_INTERNAL)
|
if (rc6 != 0 && herrno == NETDB_INTERNAL)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/* If the IPv6 lookup has been successful do not use the
|
|
||||||
buffer used in that lookup, use a new one. */
|
|
||||||
if (status[0] == NSS_STATUS_SUCCESS && rc6 == 0)
|
|
||||||
{
|
|
||||||
tmpbuf4len = 512;
|
|
||||||
tmpbuf4 = alloca (tmpbuf4len);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tmpbuf4len = tmpbuf6len;
|
|
||||||
tmpbuf4 = tmpbuf6;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Next collect IPv4 information. */
|
/* Next collect IPv4 information. */
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
rc4 = 0;
|
rc4 = 0;
|
||||||
status[1] = DL_CALL_FCT (fct, (key, AF_INET, &th[1], tmpbuf4,
|
status[1] = DL_CALL_FCT (fct, (key, AF_INET, &th[1],
|
||||||
tmpbuf4len, &rc4, &herrno,
|
tmpbuf4.data, tmpbuf4.length,
|
||||||
|
&rc4, &herrno,
|
||||||
ttl == INT32_MAX ? &ttl : NULL,
|
ttl == INT32_MAX ? &ttl : NULL,
|
||||||
canon == NULL ? &canon : NULL));
|
canon == NULL ? &canon : NULL));
|
||||||
if (rc4 != ERANGE || herrno != NETDB_INTERNAL)
|
if (rc4 != ERANGE || herrno != NETDB_INTERNAL)
|
||||||
break;
|
break;
|
||||||
tmpbuf4 = extend_alloca (tmpbuf4, tmpbuf4len, 2 * tmpbuf4len);
|
if (!scratch_buffer_grow (&tmpbuf4))
|
||||||
|
{
|
||||||
|
rc4 = ENOMEM;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rc4 != 0 && herrno == NETDB_INTERNAL)
|
if (rc4 != 0 && herrno == NETDB_INTERNAL)
|
||||||
@ -281,13 +288,11 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req,
|
|||||||
cfct = __nss_lookup_function (nip, "getcanonname_r");
|
cfct = __nss_lookup_function (nip, "getcanonname_r");
|
||||||
if (cfct != NULL)
|
if (cfct != NULL)
|
||||||
{
|
{
|
||||||
const size_t max_fqdn_len = 256;
|
|
||||||
char *buf = alloca (max_fqdn_len);
|
|
||||||
char *s;
|
char *s;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (DL_CALL_FCT (cfct, (key, buf, max_fqdn_len, &s,
|
if (DL_CALL_FCT (cfct, (key, canonbuf.data, canonbuf.length,
|
||||||
&rc, &herrno))
|
&s, &rc, &herrno))
|
||||||
== NSS_STATUS_SUCCESS)
|
== NSS_STATUS_SUCCESS)
|
||||||
canon = s;
|
canon = s;
|
||||||
else
|
else
|
||||||
@ -316,18 +321,20 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req,
|
|||||||
addrfamily = AF_INET6;
|
addrfamily = AF_INET6;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t tmpbuflen = 512;
|
|
||||||
char *tmpbuf = alloca (tmpbuflen);
|
|
||||||
int rc;
|
int rc;
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
rc = __gethostbyaddr2_r (addr, addrlen, addrfamily,
|
rc = __gethostbyaddr2_r (addr, addrlen, addrfamily,
|
||||||
&hstent_mem, tmpbuf, tmpbuflen,
|
&hstent_mem,
|
||||||
|
canonbuf.data, canonbuf.length,
|
||||||
&hstent, &herrno, NULL);
|
&hstent, &herrno, NULL);
|
||||||
if (rc != ERANGE || herrno != NETDB_INTERNAL)
|
if (rc != ERANGE || herrno != NETDB_INTERNAL)
|
||||||
break;
|
break;
|
||||||
tmpbuf = extend_alloca (tmpbuf, tmpbuflen,
|
if (!scratch_buffer_grow (&canonbuf))
|
||||||
tmpbuflen * 2);
|
{
|
||||||
|
rc = ENOMEM;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rc == 0)
|
if (rc == 0)
|
||||||
@ -531,6 +538,10 @@ next_nip:
|
|||||||
dh->usable = false;
|
dh->usable = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scratch_buffer_free (&tmpbuf6);
|
||||||
|
scratch_buffer_free (&tmpbuf4);
|
||||||
|
scratch_buffer_free (&canonbuf);
|
||||||
|
|
||||||
return timeout;
|
return timeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user