getaddrinfo: Convert from extend_alloca to struct scratch_buffer
This commit is contained in:
parent
b7db760660
commit
cd065b6843
|
@ -1,3 +1,12 @@
|
||||||
|
2016-05-12 Florian Weimer <fweimer@redhat.com>
|
||||||
|
|
||||||
|
* sysdeps/posix/getaddrinfo.c (gaih_inet_serv): Add tmpbuf
|
||||||
|
argument. Use scratch buffer instead of extend_alloca.
|
||||||
|
(gethosts): Use scratch buffer instead of extend_alloca.
|
||||||
|
(gaih_inet): Add tmpbuf argument. Use scratch buffer instead of
|
||||||
|
extend_alloca.
|
||||||
|
(getaddrinfo): Allocate scratch buffer and pass it to gaih_inet.
|
||||||
|
|
||||||
2016-05-11 Joseph Myers <joseph@codesourcery.com>
|
2016-05-11 Joseph Myers <joseph@codesourcery.com>
|
||||||
|
|
||||||
[BZ #20055]
|
[BZ #20055]
|
||||||
|
|
|
@ -1,3 +1,21 @@
|
||||||
|
/* Host and service name lookups using Name Service Switch modules.
|
||||||
|
Copyright (C) 1996-2016 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with the GNU C Library; if not, see
|
||||||
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
/* The Inner Net License, Version 2.00
|
/* The Inner Net License, Version 2.00
|
||||||
|
|
||||||
The author(s) grant permission for redistribution and use in source and
|
The author(s) grant permission for redistribution and use in source and
|
||||||
|
@ -63,6 +81,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <nscd/nscd-client.h>
|
#include <nscd/nscd-client.h>
|
||||||
#include <nscd/nscd_proto.h>
|
#include <nscd/nscd_proto.h>
|
||||||
#include <resolv/res_hconf.h>
|
#include <resolv/res_hconf.h>
|
||||||
|
#include <scratch_buffer.h>
|
||||||
|
|
||||||
#ifdef HAVE_LIBIDN
|
#ifdef HAVE_LIBIDN
|
||||||
extern int __idna_to_ascii_lz (const char *input, char **output, int flags);
|
extern int __idna_to_ascii_lz (const char *input, char **output, int flags);
|
||||||
|
@ -135,24 +154,24 @@ static const struct addrinfo default_hints =
|
||||||
|
|
||||||
static int
|
static int
|
||||||
gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
|
gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
|
||||||
const struct addrinfo *req, struct gaih_servtuple *st)
|
const struct addrinfo *req, struct gaih_servtuple *st,
|
||||||
|
struct scratch_buffer *tmpbuf)
|
||||||
{
|
{
|
||||||
struct servent *s;
|
struct servent *s;
|
||||||
size_t tmpbuflen = 1024;
|
|
||||||
struct servent ts;
|
struct servent ts;
|
||||||
char *tmpbuf;
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
tmpbuf = __alloca (tmpbuflen);
|
r = __getservbyname_r (servicename, tp->name, &ts,
|
||||||
|
tmpbuf->data, tmpbuf->length, &s);
|
||||||
r = __getservbyname_r (servicename, tp->name, &ts, tmpbuf, tmpbuflen,
|
|
||||||
&s);
|
|
||||||
if (r != 0 || s == NULL)
|
if (r != 0 || s == NULL)
|
||||||
{
|
{
|
||||||
if (r == ERANGE)
|
if (r == ERANGE)
|
||||||
tmpbuflen *= 2;
|
{
|
||||||
|
if (!scratch_buffer_grow (tmpbuf))
|
||||||
|
return -EAI_MEMORY;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return -EAI_SERVICE;
|
return -EAI_SERVICE;
|
||||||
}
|
}
|
||||||
|
@ -227,26 +246,15 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req,
|
||||||
no_data = 0; \
|
no_data = 0; \
|
||||||
while (1) { \
|
while (1) { \
|
||||||
rc = 0; \
|
rc = 0; \
|
||||||
status = DL_CALL_FCT (fct, (name, _family, &th, tmpbuf, tmpbuflen, \
|
status = DL_CALL_FCT (fct, (name, _family, &th, \
|
||||||
|
tmpbuf->data, tmpbuf->length, \
|
||||||
&rc, &herrno, NULL, &localcanon)); \
|
&rc, &herrno, NULL, &localcanon)); \
|
||||||
if (rc != ERANGE || herrno != NETDB_INTERNAL) \
|
if (rc != ERANGE || herrno != NETDB_INTERNAL) \
|
||||||
break; \
|
break; \
|
||||||
if (!malloc_tmpbuf && __libc_use_alloca (alloca_used + 2 * tmpbuflen)) \
|
if (!scratch_buffer_grow (tmpbuf)) \
|
||||||
tmpbuf = extend_alloca_account (tmpbuf, tmpbuflen, 2 * tmpbuflen, \
|
|
||||||
alloca_used); \
|
|
||||||
else \
|
|
||||||
{ \
|
{ \
|
||||||
char *newp = realloc (malloc_tmpbuf ? tmpbuf : NULL, \
|
result = -EAI_MEMORY; \
|
||||||
2 * tmpbuflen); \
|
goto free_and_return; \
|
||||||
if (newp == NULL) \
|
|
||||||
{ \
|
|
||||||
_res.options |= old_res_options & RES_USE_INET6; \
|
|
||||||
result = -EAI_MEMORY; \
|
|
||||||
goto free_and_return; \
|
|
||||||
} \
|
|
||||||
tmpbuf = newp; \
|
|
||||||
malloc_tmpbuf = true; \
|
|
||||||
tmpbuflen = 2 * tmpbuflen; \
|
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
if (status == NSS_STATUS_SUCCESS && rc == 0) \
|
if (status == NSS_STATUS_SUCCESS && rc == 0) \
|
||||||
|
@ -308,7 +316,7 @@ extern service_user *__nss_hosts_database attribute_hidden;
|
||||||
static int
|
static int
|
||||||
gaih_inet (const char *name, const struct gaih_service *service,
|
gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
const struct addrinfo *req, struct addrinfo **pai,
|
const struct addrinfo *req, struct addrinfo **pai,
|
||||||
unsigned int *naddrs)
|
unsigned int *naddrs, struct scratch_buffer *tmpbuf)
|
||||||
{
|
{
|
||||||
const struct gaih_typeproto *tp = gaih_inet_typeproto;
|
const struct gaih_typeproto *tp = gaih_inet_typeproto;
|
||||||
struct gaih_servtuple *st = (struct gaih_servtuple *) &nullserv;
|
struct gaih_servtuple *st = (struct gaih_servtuple *) &nullserv;
|
||||||
|
@ -317,7 +325,10 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
bool got_ipv6 = false;
|
bool got_ipv6 = false;
|
||||||
const char *canon = NULL;
|
const char *canon = NULL;
|
||||||
const char *orig_name = name;
|
const char *orig_name = name;
|
||||||
size_t alloca_used = 0;
|
|
||||||
|
/* Reserve stack memory for the scratch buffer in the getaddrinfo
|
||||||
|
function. */
|
||||||
|
size_t alloca_used = sizeof (struct scratch_buffer);
|
||||||
|
|
||||||
if (req->ai_protocol || req->ai_socktype)
|
if (req->ai_protocol || req->ai_socktype)
|
||||||
{
|
{
|
||||||
|
@ -352,7 +363,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
st = (struct gaih_servtuple *)
|
st = (struct gaih_servtuple *)
|
||||||
alloca_account (sizeof (struct gaih_servtuple), alloca_used);
|
alloca_account (sizeof (struct gaih_servtuple), alloca_used);
|
||||||
|
|
||||||
if ((rc = gaih_inet_serv (service->name, tp, req, st)))
|
if ((rc = gaih_inet_serv (service->name, tp, req, st, tmpbuf)))
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -377,7 +388,8 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
alloca_account (sizeof (struct gaih_servtuple),
|
alloca_account (sizeof (struct gaih_servtuple),
|
||||||
alloca_used);
|
alloca_used);
|
||||||
|
|
||||||
if ((rc = gaih_inet_serv (service->name, tp, req, newp)))
|
if ((rc = gaih_inet_serv (service->name,
|
||||||
|
tp, req, newp, tmpbuf)))
|
||||||
{
|
{
|
||||||
if (rc)
|
if (rc)
|
||||||
continue;
|
continue;
|
||||||
|
@ -438,9 +450,8 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
struct gaih_addrtuple *addrmem = NULL;
|
struct gaih_addrtuple *addrmem = NULL;
|
||||||
bool malloc_canonbuf = false;
|
bool malloc_canonbuf = false;
|
||||||
char *canonbuf = NULL;
|
char *canonbuf = NULL;
|
||||||
bool malloc_tmpbuf = false;
|
|
||||||
char *tmpbuf = NULL;
|
|
||||||
int result = 0;
|
int result = 0;
|
||||||
|
|
||||||
if (name != NULL)
|
if (name != NULL)
|
||||||
{
|
{
|
||||||
at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used);
|
at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used);
|
||||||
|
@ -608,11 +619,6 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
if (req->ai_family == AF_INET
|
if (req->ai_family == AF_INET
|
||||||
&& (req->ai_flags & AI_CANONNAME) == 0)
|
&& (req->ai_flags & AI_CANONNAME) == 0)
|
||||||
{
|
{
|
||||||
/* Allocate additional room for struct host_data. */
|
|
||||||
size_t tmpbuflen = (512 + MAX_NR_ALIASES * sizeof(char*)
|
|
||||||
+ 16 * sizeof(char));
|
|
||||||
assert (tmpbuf == NULL);
|
|
||||||
tmpbuf = alloca_account (tmpbuflen, alloca_used);
|
|
||||||
int rc;
|
int rc;
|
||||||
struct hostent th;
|
struct hostent th;
|
||||||
struct hostent *h;
|
struct hostent *h;
|
||||||
|
@ -620,28 +626,15 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
rc = __gethostbyname2_r (name, AF_INET, &th, tmpbuf,
|
rc = __gethostbyname2_r (name, AF_INET, &th,
|
||||||
tmpbuflen, &h, &herrno);
|
tmpbuf->data, tmpbuf->length,
|
||||||
|
&h, &herrno);
|
||||||
if (rc != ERANGE || herrno != NETDB_INTERNAL)
|
if (rc != ERANGE || herrno != NETDB_INTERNAL)
|
||||||
break;
|
break;
|
||||||
|
if (!scratch_buffer_grow (tmpbuf))
|
||||||
if (!malloc_tmpbuf
|
|
||||||
&& __libc_use_alloca (alloca_used + 2 * tmpbuflen))
|
|
||||||
tmpbuf = extend_alloca_account (tmpbuf, tmpbuflen,
|
|
||||||
2 * tmpbuflen,
|
|
||||||
alloca_used);
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
char *newp = realloc (malloc_tmpbuf ? tmpbuf : NULL,
|
result = -EAI_MEMORY;
|
||||||
2 * tmpbuflen);
|
goto free_and_return;
|
||||||
if (newp == NULL)
|
|
||||||
{
|
|
||||||
result = -EAI_MEMORY;
|
|
||||||
goto free_and_return;
|
|
||||||
}
|
|
||||||
tmpbuf = newp;
|
|
||||||
malloc_tmpbuf = true;
|
|
||||||
tmpbuflen = 2 * tmpbuflen;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -835,22 +828,6 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
old_res_options = _res.options;
|
old_res_options = _res.options;
|
||||||
_res.options &= ~RES_USE_INET6;
|
_res.options &= ~RES_USE_INET6;
|
||||||
|
|
||||||
size_t tmpbuflen = 1024 + sizeof(struct gaih_addrtuple);
|
|
||||||
malloc_tmpbuf = !__libc_use_alloca (alloca_used + tmpbuflen);
|
|
||||||
assert (tmpbuf == NULL);
|
|
||||||
if (!malloc_tmpbuf)
|
|
||||||
tmpbuf = alloca_account (tmpbuflen, alloca_used);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tmpbuf = malloc (tmpbuflen);
|
|
||||||
if (tmpbuf == NULL)
|
|
||||||
{
|
|
||||||
_res.options |= old_res_options & RES_USE_INET6;
|
|
||||||
result = -EAI_MEMORY;
|
|
||||||
goto free_and_return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!no_more)
|
while (!no_more)
|
||||||
{
|
{
|
||||||
no_data = 0;
|
no_data = 0;
|
||||||
|
@ -868,8 +845,9 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
rc = 0;
|
rc = 0;
|
||||||
status = DL_CALL_FCT (fct4, (name, pat, tmpbuf,
|
status = DL_CALL_FCT (fct4, (name, pat,
|
||||||
tmpbuflen, &rc, &herrno,
|
tmpbuf->data, tmpbuf->length,
|
||||||
|
&rc, &herrno,
|
||||||
NULL));
|
NULL));
|
||||||
if (status == NSS_STATUS_SUCCESS)
|
if (status == NSS_STATUS_SUCCESS)
|
||||||
break;
|
break;
|
||||||
|
@ -883,24 +861,11 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!malloc_tmpbuf
|
if (!scratch_buffer_grow (tmpbuf))
|
||||||
&& __libc_use_alloca (alloca_used + 2 * tmpbuflen))
|
|
||||||
tmpbuf = extend_alloca_account (tmpbuf, tmpbuflen,
|
|
||||||
2 * tmpbuflen,
|
|
||||||
alloca_used);
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
char *newp = realloc (malloc_tmpbuf ? tmpbuf : NULL,
|
_res.options |= old_res_options & RES_USE_INET6;
|
||||||
2 * tmpbuflen);
|
result = -EAI_MEMORY;
|
||||||
if (newp == NULL)
|
goto free_and_return;
|
||||||
{
|
|
||||||
_res.options |= old_res_options & RES_USE_INET6;
|
|
||||||
result = -EAI_MEMORY;
|
|
||||||
goto free_and_return;
|
|
||||||
}
|
|
||||||
tmpbuf = newp;
|
|
||||||
malloc_tmpbuf = true;
|
|
||||||
tmpbuflen = 2 * tmpbuflen;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1287,8 +1252,6 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||||
free (addrmem);
|
free (addrmem);
|
||||||
if (malloc_canonbuf)
|
if (malloc_canonbuf)
|
||||||
free (canonbuf);
|
free (canonbuf);
|
||||||
if (malloc_tmpbuf)
|
|
||||||
free (tmpbuf);
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -2423,7 +2386,11 @@ getaddrinfo (const char *name, const char *service,
|
||||||
if (hints->ai_family == AF_UNSPEC || hints->ai_family == AF_INET
|
if (hints->ai_family == AF_UNSPEC || hints->ai_family == AF_INET
|
||||||
|| hints->ai_family == AF_INET6)
|
|| hints->ai_family == AF_INET6)
|
||||||
{
|
{
|
||||||
last_i = gaih_inet (name, pservice, hints, end, &naddrs);
|
struct scratch_buffer tmpbuf;
|
||||||
|
scratch_buffer_init (&tmpbuf);
|
||||||
|
last_i = gaih_inet (name, pservice, hints, end, &naddrs, &tmpbuf);
|
||||||
|
scratch_buffer_free (&tmpbuf);
|
||||||
|
|
||||||
if (last_i != 0)
|
if (last_i != 0)
|
||||||
{
|
{
|
||||||
freeaddrinfo (p);
|
freeaddrinfo (p);
|
||||||
|
|
Loading…
Reference in New Issue