aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSiddhesh Poyarekar <siddhesh@redhat.com>2013-10-25 10:22:12 +0530
committerAdhemerval Zanella <azanella@linux.vnet.ibm.com>2015-01-15 14:28:16 -0500
commit9b951f59aa3c2f2d58d398aab146951216f9ff8d (patch)
tree7261ae021cf1db27c8b16349a17c8343bac74b76
parent302c61e2d3536a6ff99d518499771afd6a951b0c (diff)
downloadglibc-9b951f59aa3c2f2d58d398aab146951216f9ff8d.zip
glibc-9b951f59aa3c2f2d58d398aab146951216f9ff8d.tar.gz
glibc-9b951f59aa3c2f2d58d398aab146951216f9ff8d.tar.bz2
Fix stack overflow due to large AF_INET6 requests
Resolves #16072 (CVE-2013-4458). This patch fixes another stack overflow in getaddrinfo when it is called with AF_INET6. The AF_UNSPEC case was fixed as CVE-2013-1914, but the AF_INET6 case went undetected back then.
-rw-r--r--ChangeLog6
-rw-r--r--NEWS5
-rw-r--r--sysdeps/posix/getaddrinfo.c20
3 files changed, 28 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index 98203d0..f68d42e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2013-10-25 Siddhesh Poyarekar <siddhesh@redhat.com>
+
+ [BZ #16072]
+ * sysdeps/posix/getaddrinfo.c (gethosts): Allocate tmpbuf on
+ heap for large requests.
+
2013-02-12 Andreas Schwab <schwab@suse.de>
[BZ #15078]
diff --git a/NEWS b/NEWS
index 5d8a855..5aa982b 100644
--- a/NEWS
+++ b/NEWS
@@ -10,7 +10,10 @@ Version 2.16.1
* The following bugs are resolved with this release:
6530, 14195, 14459, 14476, 14562, 14621, 14648, 14756, 14831, 15078.,
- 15755.
+ 15755, 16072.
+
+* CVE-2013-4458 Stack overflow in getaddrinfo with large number of results
+ for AF_INET6 has been fixed (Bugzilla #16072).
* CVE-2013-2207 Incorrectly granting access to another user's pseudo-terminal
has been fixed by disabling the use of pt_chown (Bugzilla #15755).
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
index 2eca2ae..0146eb9 100644
--- a/sysdeps/posix/getaddrinfo.c
+++ b/sysdeps/posix/getaddrinfo.c
@@ -196,7 +196,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; \
@@ -208,7 +223,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; \