diff options
author | Siddhesh Poyarekar <siddhesh@redhat.com> | 2013-10-25 10:22:12 +0530 |
---|---|---|
committer | Adhemerval Zanella <azanella@linux.vnet.ibm.com> | 2015-01-15 14:28:16 -0500 |
commit | 9b951f59aa3c2f2d58d398aab146951216f9ff8d (patch) | |
tree | 7261ae021cf1db27c8b16349a17c8343bac74b76 | |
parent | 302c61e2d3536a6ff99d518499771afd6a951b0c (diff) | |
download | glibc-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-- | ChangeLog | 6 | ||||
-rw-r--r-- | NEWS | 5 | ||||
-rw-r--r-- | sysdeps/posix/getaddrinfo.c | 20 |
3 files changed, 28 insertions, 3 deletions
@@ -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] @@ -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; \ |