]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Fix stack overflow due to large AF_INET6 requests archlinux/2.18/master
authorSiddhesh Poyarekar <siddhesh@redhat.com>
Fri, 25 Oct 2013 04:52:12 +0000 (10:22 +0530)
committerAllan McRae <allan@archlinux.org>
Fri, 25 Oct 2013 13:59:00 +0000 (23:59 +1000)
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.

(cherry picked from commit 7cbcdb3699584db8913ca90f705d6337633ee10f)

Conflicts:
NEWS

ChangeLog
sysdeps/posix/getaddrinfo.c

index 3b61bc8ce72ba2ed7422fa9e486f3e659f32f230..1bb856896b17f99fdf3adee8a68f721c48b78d48 100644 (file)
--- 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]
index 8a27f0ddb705453d10726e1507a254639ee27c69..09aeb38e6bb44c5b313c5ed365180c4aa73df1a7 100644 (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;                                                  \