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.
This commit is contained in:
Siddhesh Poyarekar 2013-10-25 10:22:12 +05:30
parent 894f3f1049
commit 7cbcdb3699
3 changed files with 28 additions and 3 deletions

View file

@ -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]

5
NEWS
View file

@ -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.

View file

@ -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; \