diff options
author | Andreas Schwab <schwab@suse.de> | 2013-03-21 15:50:27 +0100 |
---|---|---|
committer | Andreas Schwab <schwab@suse.de> | 2013-04-03 17:39:15 +0200 |
commit | 1cef1b19089528db11f221e938f60b9b048945d7 (patch) | |
tree | 574123f937b0a706451c792b65189bbee2c1c35f | |
parent | 74d87055bfeb31ea37bc2356d88c065c612e1c0e (diff) | |
download | glibc-1cef1b19089528db11f221e938f60b9b048945d7.tar glibc-1cef1b19089528db11f221e938f60b9b048945d7.tar.gz glibc-1cef1b19089528db11f221e938f60b9b048945d7.tar.bz2 glibc-1cef1b19089528db11f221e938f60b9b048945d7.zip |
Fix stack overflow in getaddrinfo with many results
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | NEWS | 5 | ||||
-rw-r--r-- | sysdeps/posix/getaddrinfo.c | 23 |
3 files changed, 31 insertions, 3 deletions
@@ -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) @@ -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 diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c index d95c2d1156..230928181c 100644 --- a/sysdeps/posix/getaddrinfo.c +++ b/sysdeps/posix/getaddrinfo.c @@ -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); |