From 7cbcdb3699584db8913ca90f705d6337633ee10f Mon Sep 17 00:00:00 2001 From: Siddhesh Poyarekar <siddhesh@redhat.com> Date: Fri, 25 Oct 2013 10:22:12 +0530 Subject: [PATCH] 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. --- ChangeLog | 6 ++++++ NEWS | 5 ++++- sysdeps/posix/getaddrinfo.c | 20 ++++++++++++++++++-- 3 files changed, 28 insertions(+), 3 deletions(-) #diff --git a/ChangeLog b/ChangeLog #index 85cc5da..05a8f05 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-10-25 Aurelien Jarno <aurelien@aurel32.net> # # [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; \ -- 1.7.1