r5871 - glibc-package/branches/glibc-branch-wheezy/debian/patches/any
Author: aurel32
Date: 2013-12-05 22:19:39 +0000 (Thu, 05 Dec 2013)
New Revision: 5871
Modified:
glibc-package/branches/glibc-branch-wheezy/debian/patches/any/cvs-CVE-2013-4458.diff
Log:
Fixes for cvs-CVE-2013-4458.diff
Modified: glibc-package/branches/glibc-branch-wheezy/debian/patches/any/cvs-CVE-2013-4458.diff
===================================================================
--- glibc-package/branches/glibc-branch-wheezy/debian/patches/any/cvs-CVE-2013-4458.diff 2013-12-05 09:52:51 UTC (rev 5870)
+++ glibc-package/branches/glibc-branch-wheezy/debian/patches/any/cvs-CVE-2013-4458.diff 2013-12-05 22:19:39 UTC (rev 5871)
@@ -4,6 +4,11 @@
* sysdeps/posix/getaddrinfo.c (gethosts): Allocate tmpbuf on
heap for large requests.
+2011-06-10 Andreas Schwab <schwab@redhat.com>
+
+ * sysdeps/posix/getaddrinfo.c (gaih_inet): Fix logic allocating
+ tmpbuf.
+
2011-05-20 Ulrich Drepper <drepper@gmail.com>
[BZ #11869]
@@ -11,9 +16,15 @@
alloca.
* include/alloca.h (extend_alloca_account): Define.
+2011-04-28 Maciej Babinski <mbabinski@google.com>
+
+ [BZ #12714]
+ * sysdeps/posix/getaddrinfo.c (gaih_inet): Don't bypass
+ gethostbyname4_r when IPv6 results are possible.
+
--- a/include/alloca.h
+++ b/include/alloca.h
-@@ -49,15 +49,24 @@ libc_hidden_proto (__libc_alloca_cutoff)
+@@ -49,15 +49,24 @@
#if defined stackinfo_get_sp && defined stackinfo_sub_sp
# define alloca_account(size, avar) \
@@ -43,11 +54,43 @@
#endif
#endif
-diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
-index 7bd89c4..5ddda88 100644
--- a/sysdeps/posix/getaddrinfo.c
+++ b/sysdeps/posix/getaddrinfo.c
-@@ -278,6 +278,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
+@@ -196,7 +196,22 @@
+ &rc, &herrno, NULL, &localcanon)); \
+ if (rc != ERANGE || herrno != NETDB_INTERNAL) \
+ break; \
+- tmpbuf = extend_alloca (tmpbuf, tmpbuflen, 2 * tmpbuflen); \
++ 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, \
++ 2 * tmpbuflen); \
++ if (newp == NULL) \
++ { \
++ result = -EAI_MEMORY; \
++ goto free_and_return; \
++ } \
++ tmpbuf = newp; \
++ malloc_tmpbuf = true; \
++ tmpbuflen = 2 * tmpbuflen; \
++ } \
+ } \
+ if (status == NSS_STATUS_SUCCESS && rc == 0) \
+ h = &th; \
+@@ -208,7 +223,8 @@
+ { \
+ __set_h_errno (herrno); \
+ _res.options |= old_res_options & RES_USE_INET6; \
+- return -EAI_SYSTEM; \
++ result = -EAI_SYSTEM; \
++ goto free_and_return; \
+ } \
+ if (herrno == TRY_AGAIN) \
+ no_data = EAI_AGAIN; \
+@@ -278,6 +294,7 @@
bool got_ipv6 = false;
const char *canon = NULL;
const char *orig_name = name;
@@ -55,7 +98,7 @@
if (req->ai_protocol || req->ai_socktype)
{
-@@ -310,7 +311,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
+@@ -310,7 +327,7 @@
if (tp->name[0])
{
st = (struct gaih_servtuple *)
@@ -64,7 +107,7 @@
if ((rc = gaih_inet_serv (service->name, tp, req, st)))
return rc;
-@@ -334,7 +335,8 @@ gaih_inet (const char *name, const struct gaih_service *service,
+@@ -334,7 +351,8 @@
continue;
newp = (struct gaih_servtuple *)
@@ -74,7 +117,7 @@
if ((rc = gaih_inet_serv (service->name, tp, req, newp)))
{
-@@ -362,7 +364,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
+@@ -362,7 +380,7 @@
if (req->ai_socktype || req->ai_protocol)
{
@@ -83,7 +126,7 @@
st->next = NULL;
st->socktype = tp->socktype;
st->protocol = ((tp->protoflag & GAI_PROTO_PROTOANY)
-@@ -379,7 +381,8 @@ gaih_inet (const char *name, const struct gaih_service *service,
+@@ -379,7 +397,8 @@
{
struct gaih_servtuple *newp;
@@ -93,7 +136,7 @@
newp->next = NULL;
newp->socktype = tp->socktype;
newp->protocol = tp->protocol;
-@@ -391,10 +394,17 @@ gaih_inet (const char *name, const struct gaih_service *service,
+@@ -391,10 +410,17 @@
}
}
@@ -113,7 +156,7 @@
at->family = AF_UNSPEC;
at->scopeid = 0;
at->next = NULL;
-@@ -412,6 +422,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
+@@ -412,6 +438,7 @@
rc = __idna_to_ascii_lz (name, &p, idn_flags);
if (rc != IDNA_SUCCESS)
{
@@ -121,7 +164,7 @@
if (rc == IDNA_MALLOC_ERROR)
return -EAI_MEMORY;
if (rc == IDNA_DLOPEN_ERROR)
-@@ -421,10 +432,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
+@@ -421,10 +448,7 @@
/* In case the output string is the same as the input string
no new string has been allocated. */
if (p != name)
@@ -133,7 +176,7 @@
}
#endif
-@@ -441,23 +449,59 @@ gaih_inet (const char *name, const struct gaih_service *service,
+@@ -441,23 +465,59 @@
at->family = AF_INET6;
}
else
@@ -201,7 +244,7 @@
{
if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
at->family = AF_INET6;
-@@ -468,7 +512,10 @@ gaih_inet (const char *name, const struct gaih_service *service,
+@@ -468,7 +528,10 @@
at->family = AF_INET;
}
else
@@ -213,7 +256,7 @@
if (scope_delim != NULL)
{
-@@ -490,7 +537,10 @@ gaih_inet (const char *name, const struct gaih_service *service,
+@@ -490,7 +553,10 @@
at->scopeid = (uint32_t) strtoul (scope_delim + 1, &end,
10);
if (*end != '\0')
@@ -225,7 +268,20 @@
}
}
-@@ -517,7 +567,8 @@ gaih_inet (const char *name, const struct gaih_service *service,
+@@ -510,53 +576,81 @@
+ int no_more;
+ int old_res_options;
+
+- /* If we do not have to look for IPv4 and IPv6 together, use
+- the simple, old functions. */
+- if (req->ai_family == AF_INET
+- || (req->ai_family == AF_INET6
+- && ((req->ai_flags & AI_V4MAPPED) == 0
+- || (req->ai_flags & AI_ALL) == 0)))
++ /* If we do not have to look for IPv6 addresses, use
++ the simple, old functions, which do not support
++ IPv6 scope ids. */
++ if (req->ai_family == AF_INET)
{
int family = req->ai_family;
size_t tmpbuflen = 512;
@@ -235,7 +291,12 @@
int rc;
struct hostent th;
struct hostent *h;
-@@ -529,50 +580,95 @@ gaih_inet (const char *name, const struct gaih_service *service,
+ int herrno;
+
+- simple_again:
+ while (1)
+ {
+ rc = __gethostbyname2_r (name, family, &th, tmpbuf,
tmpbuflen, &h, &herrno);
if (rc != ERANGE || herrno != NETDB_INTERNAL)
break;
@@ -263,31 +324,12 @@
if (rc == 0)
{
- if (h != NULL)
-- /* We found data, now convert it into the list. */
-- for (int i = 0; h->h_addr_list[i]; ++i)
-- {
-- if (*pat == NULL)
-- {
-- *pat = __alloca (sizeof (struct gaih_addrtuple));
-- (*pat)->scopeid = 0;
-- }
-- (*pat)->next = NULL;
-- (*pat)->family = req->ai_family;
-- if (family == req->ai_family)
-- memcpy ((*pat)->addr, h->h_addr_list[i],
-- h->h_length);
-- else
-- {
-- uint32_t *addr = (uint32_t *) (*pat)->addr;
-- addr[3] = *(uint32_t *) h->h_addr_list[i];
-- addr[2] = htonl (0xffff);
-- addr[1] = 0;
-- addr[0] = 0;
-- }
-- pat = &((*pat)->next);
-- }
-+ {
+- if (h == NULL)
++ if (h != NULL)
+ {
+- if (req->ai_family == AF_INET6
+- && (req->ai_flags & AI_V4MAPPED)
+- && family == AF_INET6)
+ int i;
+ /* We found data, count the number of addresses. */
+ for (i = 0; h->h_addr_list[i]; ++i)
@@ -300,7 +342,11 @@
+ addrmem = alloca_account (i * sizeof (struct gaih_addrtuple),
+ alloca_used);
+ else
-+ {
+ {
+- /* Try again, this time looking for IPv4
+- addresses. */
+- family = AF_INET;
+- goto simple_again;
+ addrmem = malloc (i
+ * sizeof (struct gaih_addrtuple));
+ if (addrmem == NULL)
@@ -309,46 +355,35 @@
+ goto free_and_return;
+ }
+ malloc_addrmem = true;
-+ }
+ }
+- }
+- else
+- {
+- /* We found data, now convert it into the list. */
+- for (int i = 0; h->h_addr_list[i]; ++i)
+
+ /* Now convert it into the list. */
+ struct gaih_addrtuple *addrfree = addrmem;
+ for (i = 0; h->h_addr_list[i]; ++i)
-+ {
-+ if (*pat == NULL)
-+ {
+ {
+ if (*pat == NULL)
+ {
+- *pat = __alloca (sizeof (struct gaih_addrtuple));
+ *pat = addrfree++;
-+ (*pat)->scopeid = 0;
-+ }
-+ (*pat)->next = NULL;
-+ (*pat)->family = req->ai_family;
-+ if (family == req->ai_family)
-+ memcpy ((*pat)->addr, h->h_addr_list[i],
-+ h->h_length);
-+ else
-+ {
-+ uint32_t *addr = (uint32_t *) (*pat)->addr;
-+ addr[3] = *(uint32_t *) h->h_addr_list[i];
-+ addr[2] = htonl (0xffff);
-+ addr[1] = 0;
-+ addr[0] = 0;
-+ }
-+ pat = &((*pat)->next);
-+ }
-+ }
- }
- else
- {
+ (*pat)->scopeid = 0;
+ }
+ (*pat)->next = NULL;
+@@ -581,15 +675,16 @@
if (herrno == NETDB_INTERNAL)
{
__set_h_errno (herrno);
- return -EAI_SYSTEM;
-+ result = -EAI_SYSTEM;
- }
+- }
- if (herrno == TRY_AGAIN)
- {
- return -EAI_AGAIN;
-- }
++ result = -EAI_SYSTEM;
+ }
- /* We made requests but they turned out no data.
- The name is known, though. */
- return GAIH_OKIFUNSPEC | -EAI_NODATA;
@@ -363,7 +398,7 @@
}
goto process_list;
-@@ -596,21 +692,56 @@ gaih_inet (const char *name, const struct gaih_service *service,
+@@ -613,21 +708,56 @@
bool added_canon = (req->ai_flags & AI_CANONNAME) == 0;
char *addrs = air->addrs;
@@ -423,7 +458,7 @@
if (air->family[i] == AF_INET
&& req->ai_family == AF_INET6
-@@ -640,20 +771,26 @@ gaih_inet (const char *name, const struct gaih_service *service,
+@@ -657,20 +787,26 @@
free (air);
if (at->family == AF_UNSPEC)
@@ -456,14 +491,14 @@
}
}
#endif
-@@ -682,7 +819,19 @@ gaih_inet (const char *name, const struct gaih_service *service,
+@@ -699,7 +835,19 @@
_res.options &= ~RES_USE_INET6;
size_t tmpbuflen = 1024;
- char *tmpbuf = alloca (tmpbuflen);
+ malloc_tmpbuf = !__libc_use_alloca (alloca_used + tmpbuflen);
+ assert (tmpbuf == NULL);
-+ if (malloc_tmpbuf)
++ if (!malloc_tmpbuf)
+ tmpbuf = alloca_account (tmpbuflen, alloca_used);
+ else
+ {
@@ -477,7 +512,7 @@
while (!no_more)
{
-@@ -711,8 +860,25 @@ gaih_inet (const char *name, const struct gaih_service *service,
+@@ -728,8 +876,25 @@
no_data = herrno == NO_DATA;
break;
}
@@ -504,8 +539,8 @@
+ }
}
- no_inet6_data = no_data;
-@@ -787,18 +953,40 @@ gaih_inet (const char *name, const struct gaih_service *service,
+ if (status == NSS_STATUS_SUCCESS)
+@@ -832,18 +997,40 @@
if (cfct != NULL)
{
const size_t max_fqdn_len = 256;
@@ -551,7 +586,7 @@
}
}
status = NSS_STATUS_SUCCESS;
-@@ -833,22 +1021,27 @@ gaih_inet (const char *name, const struct gaih_service *service,
+@@ -878,22 +1065,27 @@
{
/* If both requests timed out report this. */
if (no_data == EAI_AGAIN && no_inet6_data == EAI_AGAIN)
@@ -585,7 +620,7 @@
memset (at, '\0', sizeof (struct gaih_addrtuple));
if (req->ai_family == AF_UNSPEC)
-@@ -887,30 +1080,56 @@ gaih_inet (const char *name, const struct gaih_service *service,
+@@ -932,30 +1124,56 @@
/* Only the first entry gets the canonical name. */
if (at2 == at && (req->ai_flags & AI_CANONNAME) != 0)
{
@@ -648,7 +683,7 @@
}
if (h != NULL)
-@@ -937,11 +1156,16 @@ gaih_inet (const char *name, const struct gaih_service *service,
+@@ -982,11 +1200,16 @@
int rc = __idna_to_unicode_lzlz (canon, &out, idn_flags);
if (rc != IDNA_SUCCESS)
{
@@ -669,7 +704,7 @@
}
/* In case the output string is the same as the input
string no new string has been allocated and we
-@@ -956,10 +1180,25 @@ gaih_inet (const char *name, const struct gaih_service *service,
+@@ -1001,10 +1224,25 @@
#ifdef HAVE_LIBIDN
make_copy:
#endif
@@ -698,7 +733,7 @@
}
family = at2->family;
-@@ -985,7 +1224,8 @@ gaih_inet (const char *name, const struct gaih_service *service,
+@@ -1030,7 +1268,8 @@
if (ai == NULL)
{
free ((char *) canon);
@@ -708,7 +743,7 @@
}
ai->ai_flags = req->ai_flags;
-@@ -1038,7 +1278,18 @@ gaih_inet (const char *name, const struct gaih_service *service,
+@@ -1083,7 +1322,18 @@
at2 = at2->next;
}
}
@@ -728,41 +763,3 @@
}
-diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
-index e6ce4cf..8ff74b4 100644
---- a/sysdeps/posix/getaddrinfo.c
-+++ b/sysdeps/posix/getaddrinfo.c
-@@ -197,7 +197,22 @@ gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
- &rc, &herrno, NULL, &localcanon)); \
- if (rc != ERANGE || herrno != NETDB_INTERNAL) \
- break; \
-- tmpbuf = extend_alloca (tmpbuf, tmpbuflen, 2 * tmpbuflen); \
-+ 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, \
-+ 2 * tmpbuflen); \
-+ if (newp == NULL) \
-+ { \
-+ result = -EAI_MEMORY; \
-+ goto free_and_return; \
-+ } \
-+ tmpbuf = newp; \
-+ malloc_tmpbuf = true; \
-+ tmpbuflen = 2 * tmpbuflen; \
-+ } \
- } \
- if (status == NSS_STATUS_SUCCESS && rc == 0) \
- h = &th; \
-@@ -209,7 +224,8 @@ gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
- { \
- __set_h_errno (herrno); \
- _res.options |= old_res_options & RES_USE_INET6; \
-- return -EAI_SYSTEM; \
-+ result = -EAI_SYSTEM; \
-+ goto free_and_return; \
- } \
- if (herrno == TRY_AGAIN) \
- no_data = EAI_AGAIN; \
Reply to: