From: Siddhesh Poyarekar Date: Fri, 25 Oct 2013 04:52:12 +0000 (+0530) Subject: Fix stack overflow due to large AF_INET6 requests X-Git-Tag: glibc-2.19~578 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=7cbcdb3699584db8913ca90f705d6337633ee10f;p=platform%2Fupstream%2Fglibc.git 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. --- diff --git a/ChangeLog b/ChangeLog index 85cc5da..05a8f05 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2013-10-25 Siddhesh Poyarekar + + [BZ #16072] + * sysdeps/posix/getaddrinfo.c (gethosts): Allocate tmpbuf on + heap for large requests. + 2013-10-25 Aurelien Jarno [BZ #9954] diff --git a/NEWS b/NEWS index 3358ac6..9199b90 100644 --- a/NEWS +++ b/NEWS @@ -15,7 +15,7 @@ Version 2.19 15734, 15735, 15736, 15748, 15749, 15754, 15760, 15764, 15797, 15825, 15844, 15847, 15849, 15855, 15856, 15857, 15859, 15867, 15886, 15887, 15890, 15892, 15893, 15895, 15897, 15905, 15909, 15919, 15921, 15923, - 15939, 15948, 15963, 15966, 15988, 16032, 16034, 16036, 16041. + 15939, 15948, 15963, 15966, 15988, 16032, 16034, 16036, 16041, 16072. * CVE-2012-4412 The strcoll implementation caches indices and rules for large collation sequences to optimize multiple passes. This cache @@ -44,6 +44,9 @@ Version 2.19 heap when passed very large allocation size values (Bugzilla #15855, #15856, #15857). +* CVE-2013-4458 Stack overflow in getaddrinfo with large number of results + for AF_INET6 has been fixed (Bugzilla #16072). + * New locales: ak_GH, cmn_TW, hak_TW, lzh_TW, nan_TW, quz_PE, pap_AW, pap_CW, ar_SS. 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; \