]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Fix stack overflow in getaddrinfo with many results
authorAndreas Schwab <schwab@suse.de>
Thu, 21 Mar 2013 14:50:27 +0000 (15:50 +0100)
committerAndreas Schwab <schwab@suse.de>
Wed, 3 Apr 2013 15:39:15 +0000 (17:39 +0200)
ChangeLog
NEWS
sysdeps/posix/getaddrinfo.c

index 3046d2e3ed9a4c376530b69cb8f4f73e24603c1a..deebea49f15013edfcac8a1c3097c009ba206804 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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)
diff --git a/NEWS b/NEWS
index 7718a0a14dbf3ed5553f7a3c77acfc33834a5857..8ecb2ee72ced617a4f22defa695da1f34ec057d6 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -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
index d95c2d1156baf66190df7fa7538bd4d824a4c880..230928181cbf84172a1e1a15a3e9c5cb28c9ccbf 100644 (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);