Fix stack overflow in getaddrinfo with many results

This commit is contained in:
Andreas Schwab 2013-03-21 15:50:27 +01:00
parent 74d87055bf
commit 1cef1b1908
3 changed files with 31 additions and 3 deletions

View File

@ -1,3 +1,9 @@
2013-04-03 Andreas Schwab <schwab@suse.de>
[BZ #15330]
* sysdeps/posix/getaddrinfo.c (getaddrinfo): Allocate results and
order arrays from heap if bigger than alloca cutoff.
2013-04-03 Thomas Schwinge <thomas@codesourcery.com>
* sysdeps/i386/fpu/math-tests.h (SNAN_TESTS_float)

5
NEWS
View File

@ -13,7 +13,10 @@ Version 2.18
14317, 14327, 14496, 14812, 14920, 14964, 14981, 14982, 14985, 14994,
14996, 15003, 15006, 15020, 15023, 15036, 15054, 15055, 15062, 15078,
15160, 15214, 15232, 15234, 15283, 15285, 15287, 15304, 15305, 15307,
15327.
15327, 15330.
* CVE-2013-1914 Stack overflow in getaddrinfo with many results has been
fixed (Bugzilla #15330).
* Add support for calling C++11 thread_local object destructors on thread
and program exit. This needs compiler support for offloading C++11

View File

@ -2489,11 +2489,27 @@ getaddrinfo (const char *name, const char *service,
__typeof (once) old_once = once;
__libc_once (once, gaiconf_init);
/* Sort results according to RFC 3484. */
struct sort_result results[nresults];
size_t order[nresults];
struct sort_result *results;
size_t *order;
struct addrinfo *q;
struct addrinfo *last = NULL;
char *canonname = NULL;
bool malloc_results;
malloc_results
= !__libc_use_alloca (nresults * (sizeof (*results) + sizeof (size_t)));
if (malloc_results)
{
results = malloc (nresults * (sizeof (*results) + sizeof (size_t)));
if (results == NULL)
{
__free_in6ai (in6ai);
return EAI_MEMORY;
}
}
else
results = alloca (nresults * (sizeof (*results) + sizeof (size_t)));
order = (size_t *) (results + nresults);
/* Now we definitely need the interface information. */
if (! check_pf_called)
@ -2664,6 +2680,9 @@ getaddrinfo (const char *name, const char *service,
/* Fill in the canonical name into the new first entry. */
p->ai_canonname = canonname;
if (malloc_results)
free (results);
}
__free_in6ai (in6ai);