Hi,
I've prepared a eglibc package for wheezy, available at
deb https://people.debian.org/~santiago/debian santiago-wheezy/
deb-src https://people.debian.org/~santiago/debian santiago-wheezy/
Debdiff attached, and this is the dsc:
https://people.debian.org/~santiago/debian/santiago-wheezy/eglibc_2.13-38+deb7u11~3.dsc
As usual, feedback is warmly welcome.
Cheers,
Santiago
Note to self: my current grsec setup was unable to build it. Need to fix
it:
...
GCONV_PATH=/build/eglibc-2.13/build-tree/amd64-libc/iconvdata LC_ALL=C /build/eglibc-2.13/build-tree/amd64-libc/elf/ld-linux-x86-64.so.2 --library-path /build/eglibc-2.13/build-tree/amd64-libc:/build/eglibc-2.13/build-tree/amd64-libc/math:/build/eglibc-2.13/build-tree/amd64-libc/elf:/build/eglibc-2.13/build-tree/amd64-libc/dlfcn:/build/eglibc-2.13/build-tree/amd64-libc/nss:/build/eglibc-2.13/build-tree/amd64-libc/nis:/build/eglibc-2.13/build-tree/amd64-libc/rt:/build/eglibc-2.13/build-tree/amd64-libc/resolv:/build/eglibc-2.13/build-tree/amd64-libc/crypt:/build/eglibc-2.13/build-tree/amd64-libc/nptl /build/eglibc-2.13/build-tree/amd64-libc/elf/tst-execstack-prog > /build/eglibc-2.13/build-tree/amd64-libc/elf/tst-execstack-prog.out
/build/eglibc-2.13/build-tree/amd64-libc/elf/tst-execstack-prog: error while loading shared libraries: /build/eglibc-2.13/build-tree/amd64-libc/elf/tst-execstack-prog: cannot enable executable stack as shared object requires: Permission denied
...
diff -u eglibc-2.13/debian/changelog eglibc-2.13/debian/changelog
--- eglibc-2.13/debian/changelog
+++ eglibc-2.13/debian/changelog
@@ -1,3 +1,15 @@
+eglibc (2.13-38+deb7u11~3) santiago-wheezy; urgency=medium
+
+ * Non-maintainer upload by the Debian LTS Team.
+ * any/cvs-CVE-2016-1234-glob.diff: Fix stack-based buffer overflow in the
+ glob funcion (CVE-2016-1234).
+ * any/cvs-CVE-2016-3706-getaddrinfo.diff: Fix getaddrinfo stack overflow in
+ hostent translation (CVE-2016-3706).
+ * any/cvs-CVE-2016-3075.diff: Fix stack overflow in nss_dns_getnetbyname_r
+ (CVE-2016-3075).
+
+ -- Santiago Ruano Rincón <santiagorr@riseup.net> Thu, 19 May 2016 21:17:43 +0200
+
eglibc (2.13-38+deb7u10) wheezy-security; urgency=medium
[ Aurelien Jarno ]
diff -u eglibc-2.13/debian/patches/series eglibc-2.13/debian/patches/series
--- eglibc-2.13/debian/patches/series
+++ eglibc-2.13/debian/patches/series
@@ -416,0 +417,4 @@
+any/cvs-pre-CVE-2016-1234-glob.diff
+any/cvs-CVE-2016-1234-glob.diff
+any/cvs-CVE-2016-3706-dns-network.diff
+any/cvs-CVE-2016-3706-getaddrinfo.diff
only in patch2:
unchanged:
--- eglibc-2.13.orig/debian/patches/any/cvs-CVE-2016-1234-glob.diff
+++ eglibc-2.13/debian/patches/any/cvs-CVE-2016-1234-glob.diff
@@ -0,0 +1,365 @@
+From e97fb84811238c627f93e5e703a11eb841601947 Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Wed, 4 May 2016 12:09:35 +0200
+Subject: [PATCH] CVE-2016-1234: glob: Do not copy d_name field of struct dirent [BZ #19779]
+
+Instead, we store the data we need from the return value of
+readdir in an object of the new type struct readdir_result.
+This type is independent of the layout of struct dirent.
+
+---
+
+--- a/posix/bug-glob2.c
++++ b/posix/bug-glob2.c
+@@ -41,6 +41,17 @@
+ # define PRINTF(fmt, args...)
+ #endif
+
++#define LONG_NAME \
++ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
++ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
++ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
++ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
++ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
++ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
++ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
++ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
++ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
++ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+
+ static struct
+ {
+@@ -59,6 +70,7 @@
+ { ".", 3, DT_DIR, 0755 },
+ { "..", 3, DT_DIR, 0755 },
+ { "a", 3, DT_REG, 0644 },
++ { LONG_NAME, 3, DT_REG, 0644 },
+ { "unreadable", 2, DT_DIR, 0111 },
+ { ".", 3, DT_DIR, 0111 },
+ { "..", 3, DT_DIR, 0755 },
+@@ -76,7 +88,7 @@
+ int level;
+ int idx;
+ struct dirent d;
+- char room_for_dirent[NAME_MAX];
++ char room_for_dirent[sizeof (LONG_NAME)];
+ } my_DIR;
+
+
+--- a/posix/glob.c
++++ b/posix/glob.c
+@@ -26,7 +26,9 @@
+ #include <errno.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
++#include <stdbool.h>
+ #include <stddef.h>
++#include <stdint.h>
+ #ifdef _LIBC
+ # include <gnu/option-groups.h>
+ #endif
+@@ -72,69 +74,8 @@
+ # endif /* HAVE_VMSDIR_H */
+ #endif
+
+-
+-/* When used in the GNU libc the symbol _DIRENT_HAVE_D_TYPE is available
+- if the `d_type' member for `struct dirent' is available.
+- HAVE_STRUCT_DIRENT_D_TYPE plays the same role in GNULIB. */
+-#if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE
+-/* True if the directory entry D must be of type T. */
+-# define DIRENT_MUST_BE(d, t) ((d)->d_type == (t))
+-
+-/* True if the directory entry D might be a symbolic link. */
+-# define DIRENT_MIGHT_BE_SYMLINK(d) \
+- ((d)->d_type == DT_UNKNOWN || (d)->d_type == DT_LNK)
+-
+-/* True if the directory entry D might be a directory. */
+-# define DIRENT_MIGHT_BE_DIR(d) \
+- ((d)->d_type == DT_DIR || DIRENT_MIGHT_BE_SYMLINK (d))
+-
+-#else /* !HAVE_D_TYPE */
+-# define DIRENT_MUST_BE(d, t) false
+-# define DIRENT_MIGHT_BE_SYMLINK(d) true
+-# define DIRENT_MIGHT_BE_DIR(d) true
+-#endif /* HAVE_D_TYPE */
+-
+-/* If the system has the `struct dirent64' type we use it internally. */
+-#if defined _LIBC && !defined COMPILE_GLOB64
+-
+-# if (defined POSIX || defined WINDOWS32) && !defined __GNU_LIBRARY__
+-# define CONVERT_D_INO(d64, d32)
+-# else
+-# define CONVERT_D_INO(d64, d32) \
+- (d64)->d_ino = (d32)->d_ino;
+-# endif
+-
+-# ifdef _DIRENT_HAVE_D_TYPE
+-# define CONVERT_D_TYPE(d64, d32) \
+- (d64)->d_type = (d32)->d_type;
+-# else
+-# define CONVERT_D_TYPE(d64, d32)
+-# endif
+-
+-# define CONVERT_DIRENT_DIRENT64(d64, d32) \
+- strcpy ((d64)->d_name, (d32)->d_name); \
+- CONVERT_D_INO (d64, d32) \
+- CONVERT_D_TYPE (d64, d32)
+-#endif
+-
+-
+-#if (defined POSIX || defined WINDOWS32) && !defined __GNU_LIBRARY__
+-/* Posix does not require that the d_ino field be present, and some
+- systems do not provide it. */
+-# define REAL_DIR_ENTRY(dp) 1
+-#else
+-# define REAL_DIR_ENTRY(dp) (dp->d_ino != 0)
+-#endif /* POSIX */
+-
+ #include <stdlib.h>
+ #include <string.h>
+-
+-/* NAME_MAX is usually defined in <dirent.h> or <limits.h>. */
+-#include <limits.h>
+-#ifndef NAME_MAX
+-# define NAME_MAX (sizeof (((struct dirent *) 0)->d_name))
+-#endif
+-
+ #include <alloca.h>
+
+ #ifdef _LIBC
+@@ -179,8 +120,111 @@
+
+ static const char *next_brace_sub (const char *begin, int flags) __THROW;
+
++/* A representation of a directory entry which does not depend on the
++ layout of struct dirent, or the size of ino_t. */
++struct readdir_result
++{
++ const char *name;
++# if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE
++ uint8_t type;
++# endif
++ bool skip_entry;
++};
++
++# if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE
++/* Initializer based on the d_type member of struct dirent. */
++# define D_TYPE_TO_RESULT(source) (source)->d_type,
++
++/* True if the directory entry D might be a symbolic link. */
++static bool
++readdir_result_might_be_symlink (struct readdir_result d)
++{
++ return d.type == DT_UNKNOWN || d.type == DT_LNK;
++}
++
++/* True if the directory entry D might be a directory. */
++static bool
++readdir_result_might_be_dir (struct readdir_result d)
++{
++ return d.type == DT_DIR || readdir_result_might_be_symlink (d);
++}
++# else /* defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE */
++# define D_TYPE_TO_RESULT(source)
++
++/* If we do not have type information, symbolic links and directories
++ are always a possibility. */
++
++static bool
++readdir_result_might_be_symlink (struct readdir_result d)
++{
++ return true;
++}
++
++static bool
++readdir_result_might_be_dir (struct readdir_result d)
++{
++ return true;
++}
++
++# endif /* defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE */
++
++# if (defined POSIX || defined WINDOWS32) && !defined __GNU_LIBRARY__
++/* Initializer for skip_entry. POSIX does not require that the d_ino
++ field be present, and some systems do not provide it. */
++# define D_INO_TO_RESULT(source) false,
++# else
++# define D_INO_TO_RESULT(source) (source)->d_ino == 0,
++# endif
++
++/* Construct an initializer for a struct readdir_result object from a
++ struct dirent *. No copy of the name is made. */
++#define READDIR_RESULT_INITIALIZER(source) \
++ { \
++ source->d_name, \
++ D_TYPE_TO_RESULT (source) \
++ D_INO_TO_RESULT (source) \
++ }
++
+ #endif /* !defined _LIBC || !defined GLOB_ONLY_P */
+
++/* Call gl_readdir on STREAM. This macro can be overridden to reduce
++ type safety if an old interface version needs to be supported. */
++#ifndef GL_READDIR
++# define GL_READDIR(pglob, stream) ((pglob)->gl_readdir (stream))
++#endif
++
++/* Extract name and type from directory entry. No copy of the name is
++ made. If SOURCE is NULL, result name is NULL. Keep in sync with
++ convert_dirent64 below. */
++static struct readdir_result
++convert_dirent (const struct dirent *source)
++{
++ if (source == NULL)
++ {
++ struct readdir_result result = { NULL, };
++ return result;
++ }
++ struct readdir_result result = READDIR_RESULT_INITIALIZER (source);
++ return result;
++}
++
++#ifndef COMPILE_GLOB64
++/* Like convert_dirent, but works on struct dirent64 instead. Keep in
++ sync with convert_dirent above. */
++static struct readdir_result
++convert_dirent64 (const struct dirent64 *source)
++{
++ if (source == NULL)
++ {
++ struct readdir_result result = { NULL, };
++ return result;
++ }
++ struct readdir_result result = READDIR_RESULT_INITIALIZER (source);
++ return result;
++}
++#endif
++
++
+ #ifndef attribute_hidden
+ # define attribute_hidden
+ #endif
+@@ -1530,55 +1574,36 @@
+
+ while (1)
+ {
+- const char *name;
+-#if defined _LIBC && !defined COMPILE_GLOB64
+- struct dirent64 *d;
+- union
+- {
+- struct dirent64 d64;
+- char room [offsetof (struct dirent64, d_name[0])
+- + NAME_MAX + 1];
+- }
+- d64buf;
+-
+- if (__builtin_expect (flags & GLOB_ALTDIRFUNC, 0))
+- {
+- struct dirent *d32 = (*pglob->gl_readdir) (stream);
+- if (d32 != NULL)
+- {
+- CONVERT_DIRENT_DIRENT64 (&d64buf.d64, d32);
+- d = &d64buf.d64;
+- }
+- else
+- d = NULL;
+- }
+- else
+- d = __readdir64 (stream);
++ struct readdir_result d;
++ {
++ if (__builtin_expect (flags & GLOB_ALTDIRFUNC, 0))
++ d = convert_dirent (GL_READDIR (pglob, stream));
++ else
++ {
++#ifdef COMPILE_GLOB64
++ d = convert_dirent (__readdir (stream));
+ #else
+- struct dirent *d = (__builtin_expect (flags & GLOB_ALTDIRFUNC, 0)
+- ? ((struct dirent *)
+- (*pglob->gl_readdir) (stream))
+- : __readdir (stream));
++ d = convert_dirent64 (__readdir64 (stream));
+ #endif
+- if (d == NULL)
++ }
++ }
++ if (d.name == NULL)
+ break;
+- if (! REAL_DIR_ENTRY (d))
++ if (d.skip_entry)
+ continue;
+
+ /* If we shall match only directories use the information
+ provided by the dirent call if possible. */
+- if ((flags & GLOB_ONLYDIR) && !DIRENT_MIGHT_BE_DIR (d))
++ if ((flags & GLOB_ONLYDIR) && !readdir_result_might_be_dir (d))
+ continue;
+
+- name = d->d_name;
+-
+- if (fnmatch (pattern, name, fnm_flags) == 0)
++ if (fnmatch (pattern, d.name, fnm_flags) == 0)
+ {
+ /* If the file we found is a symlink we have to
+ make sure the target file exists. */
+- if (!DIRENT_MIGHT_BE_SYMLINK (d)
+- || link_exists_p (dfd, directory, dirlen, name, pglob,
+- flags))
++ if (!readdir_result_might_be_symlink (d)
++ || link_exists_p (dfd, directory, dirlen, d.name,
++ pglob, flags))
+ {
+ if (cur == names->count)
+ {
+@@ -1598,7 +1623,7 @@
+ names = newnames;
+ cur = 0;
+ }
+- names->name[cur] = strdup (d->d_name);
++ names->name[cur] = strdup (d.name);
+ if (names->name[cur] == NULL)
+ goto memory_error;
+ ++cur;
+--- a/sysdeps/unix/sysv/linux/i386/glob64.c
++++ b/sysdeps/unix/sysv/linux/i386/glob64.c
+@@ -1,3 +1,21 @@
++/* Two glob variants with 64-bit support, for dirent64 and __olddirent64.
++ Copyright (C) 1998-2016 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, see
++ <http://www.gnu.org/licenses/>. */
++
+ #include <dirent.h>
+ #include <glob.h>
+ #include <sys/stat.h>
+@@ -38,11 +56,15 @@
+
+ #undef dirent
+ #define dirent __old_dirent64
++#undef GL_READDIR
++# define GL_READDIR(pglob, stream) \
++ ((struct __old_dirent64 *) (pglob)->gl_readdir (stream))
+ #undef __readdir
+ #define __readdir(dirp) __old_readdir64 (dirp)
+ #undef glob
+ #define glob(pattern, flags, errfunc, pglob) \
+ __old_glob64 (pattern, flags, errfunc, pglob)
++#define convert_dirent __old_convert_dirent
+ #define glob_in_dir __old_glob_in_dir
+ #define GLOB_ATTRIBUTE attribute_compat_text_section
+
only in patch2:
unchanged:
--- eglibc-2.13.orig/debian/patches/any/cvs-CVE-2016-3706-dns-network.diff
+++ eglibc-2.13/debian/patches/any/cvs-CVE-2016-3706-dns-network.diff
@@ -0,0 +1,33 @@
+Origin: upstream, a02f3e795993ae0f80242b488061b74666605625
+
+From a02f3e795993ae0f80242b488061b74666605625 Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Tue, 29 Mar 2016 12:57:56 +0200
+Subject: [PATCH] CVE-2016-3075: Stack overflow in _nss_dns_getnetbyname_r [BZ #19879]
+
+The defensive copy is not needed because the name may not alias the
+output buffer.
+
+---
+
+--- a/resolv/nss_dns/dns-network.c
++++ b/resolv/nss_dns/dns-network.c
+@@ -119,17 +119,14 @@
+ } net_buffer;
+ querybuf *orig_net_buffer;
+ int anslen;
+- char *qbuf;
+ enum nss_status status;
+
+ if (__res_maybe_init (&_res, 0) == -1)
+ return NSS_STATUS_UNAVAIL;
+
+- qbuf = strdupa (name);
+-
+ net_buffer.buf = orig_net_buffer = (querybuf *) alloca (1024);
+
+- anslen = __libc_res_nsearch (&_res, qbuf, C_IN, T_PTR, net_buffer.buf->buf,
++ anslen = __libc_res_nsearch (&_res, name, C_IN, T_PTR, net_buffer.buf->buf,
+ 1024, &net_buffer.ptr, NULL, NULL, NULL, NULL);
+ if (anslen < 0)
+ {
only in patch2:
unchanged:
--- eglibc-2.13.orig/debian/patches/any/cvs-CVE-2016-3706-getaddrinfo.diff
+++ eglibc-2.13/debian/patches/any/cvs-CVE-2016-3706-getaddrinfo.diff
@@ -0,0 +1,174 @@
+X-Git-Url: https://sourceware.org/git/gitweb.cgi?p=glibc.git;a=blobdiff_plain;f=sysdeps%2Fposix%2Fgetaddrinfo.c;h=fed2d3bf130b6fc88e5c6840804bbadb8fe9a98b;hp=1ef3f20d987bb14e9b6d22e9092304f858298c23;hb=4ab2ab03d4351914ee53248dc5aef4a8c88ff8b9;hpb=137fe72eca6923a00381a3ca9f0e7672c1f85e3f
+
+--- a/sysdeps/posix/getaddrinfo.c
++++ b/sysdeps/posix/getaddrinfo.c
+@@ -182,9 +182,58 @@
+ return 0;
+ }
+
++/* Convert struct hostent to a list of struct gaih_addrtuple objects.
++ h_name is not copied, and the struct hostent object must not be
++ deallocated prematurely. *RESULT must be NULL or a pointer to an
++ object allocated using malloc, which is freed. */
++static bool
++convert_hostent_to_gaih_addrtuple (const struct addrinfo *req,
++ int family,
++ struct hostent *h,
++ struct gaih_addrtuple **result)
++{
++ free (*result);
++ *result = NULL;
++
++ /* Count the number of addresses in h->h_addr_list. */
++ size_t count = 0;
++ for (char **p = h->h_addr_list; *p != NULL; ++p)
++ ++count;
++
++ /* Report no data if no addresses are available, or if the incoming
++ address size is larger than what we can store. */
++ if (count == 0 || h->h_length > sizeof (((struct gaih_addrtuple) {}).addr))
++ return true;
++
++ struct gaih_addrtuple *array = calloc (count, sizeof (*array));
++ if (array == NULL)
++ return false;
++
++ for (size_t i = 0; i < count; ++i)
++ {
++ if (family == AF_INET && req->ai_family == AF_INET6)
++ {
++ /* Perform address mapping. */
++ array[i].family = AF_INET6;
++ memcpy(array[i].addr + 3, h->h_addr_list[i], sizeof (uint32_t));
++ array[i].addr[2] = htonl (0xffff);
++ }
++ else
++ {
++ array[i].family = family;
++ memcpy (array[i].addr, h->h_addr_list[i], h->h_length);
++ }
++ array[i].next = array + i + 1;
++ }
++ array[0].name = h->h_name;
++ array[count - 1].next = NULL;
++
++ *result = array;
++ return true;
++}
++
+ #define gethosts(_family, _type) \
+ { \
+- int i; \
+ int herrno; \
+ struct hostent th; \
+ struct hostent *h; \
+@@ -233,36 +282,23 @@
+ } \
+ else if (h != NULL) \
+ { \
+- for (i = 0; h->h_addr_list[i]; i++) \
++ /* Make sure that addrmem can be freed. */ \
++ if (!malloc_addrmem) \
++ addrmem = NULL; \
++ if (!convert_hostent_to_gaih_addrtuple (req, _family,h, &addrmem)) \
+ { \
+- if (*pat == NULL) \
+- { \
+- *pat = __alloca (sizeof (struct gaih_addrtuple)); \
+- (*pat)->scopeid = 0; \
+- } \
+- uint32_t *addr = (*pat)->addr; \
+- (*pat)->next = NULL; \
+- (*pat)->name = i == 0 ? strdupa (h->h_name) : NULL; \
+- if (_family == AF_INET && req->ai_family == AF_INET6) \
+- { \
+- (*pat)->family = AF_INET6; \
+- addr[3] = *(uint32_t *) h->h_addr_list[i]; \
+- addr[2] = htonl (0xffff); \
+- addr[1] = 0; \
+- addr[0] = 0; \
+- } \
+- else \
+- { \
+- (*pat)->family = _family; \
+- memcpy (addr, h->h_addr_list[i], sizeof(_type)); \
+- } \
+- pat = &((*pat)->next); \
++ _res.options |= old_res_options & RES_USE_INET6; \
++ result = -EAI_SYSTEM; \
++ goto free_and_return; \
+ } \
++ *pat = addrmem; \
++ /* The conversion uses malloc unconditionally. */ \
++ malloc_addrmem = true; \
+ \
+ if (localcanon != NULL && canon == NULL) \
+ canon = strdupa (localcanon); \
+ \
+- if (_family == AF_INET6 && i > 0) \
++ if (_family == AF_INET6 && *pat != NULL) \
+ got_ipv6 = true; \
+ } \
+ }
+@@ -624,53 +660,16 @@
+ {
+ if (h != NULL)
+ {
+- int i;
+- /* We found data, count the number of addresses. */
+- for (i = 0; h->h_addr_list[i]; ++i)
+- ;
+- if (i > 0 && *pat != NULL)
+- --i;
+-
+- if (__libc_use_alloca (alloca_used
+- + i * sizeof (struct gaih_addrtuple)))
+- addrmem = alloca_account (i * sizeof (struct gaih_addrtuple),
+- alloca_used);
+- else
++ /* We found data, convert it. */
++ if (!convert_hostent_to_gaih_addrtuple
++ (req, AF_INET, h, &addrmem))
+ {
+- addrmem = malloc (i
+- * sizeof (struct gaih_addrtuple));
+- if (addrmem == NULL)
+- {
+- result = -EAI_MEMORY;
+- goto free_and_return;
+- }
+- malloc_addrmem = true;
+- }
+-
+- /* Now convert it into the list. */
+- struct gaih_addrtuple *addrfree = addrmem;
+- for (i = 0; h->h_addr_list[i]; ++i)
+- {
+- if (*pat == NULL)
+- {
+- *pat = addrfree++;
+- (*pat)->scopeid = 0;
+- }
+- (*pat)->next = NULL;
+- (*pat)->family = req->ai_family;
+- if (family == req->ai_family)
+- memcpy ((*pat)->addr, h->h_addr_list[i],
+- h->h_length);
+- else
+- {
+- uint32_t *addr = (uint32_t *) (*pat)->addr;
+- addr[3] = *(uint32_t *) h->h_addr_list[i];
+- addr[2] = htonl (0xffff);
+- addr[1] = 0;
+- addr[0] = 0;
+- }
+- pat = &((*pat)->next);
++ result = -EAI_MEMORY;
++ goto free_and_return;
+ }
++ *pat = addrmem;
++ /* The conversion uses malloc unconditionally. */
++ malloc_addrmem = true;
+ }
+ }
+ else
only in patch2:
unchanged:
--- eglibc-2.13.orig/debian/patches/any/cvs-pre-CVE-2016-1234-glob.diff
+++ eglibc-2.13/debian/patches/any/cvs-pre-CVE-2016-1234-glob.diff
@@ -0,0 +1,111 @@
+From 5ae82aa4bf45cdaafeb1c25e09897eabff210de9 Mon Sep 17 00:00:00 2001
+From: Florian Weimer <fweimer@redhat.com>
+Date: Fri, 29 Apr 2016 09:33:07 +0200
+Subject: [PATCH] glob: Simplify the interface for the GLOB_ALTDIRFUNC callback gl_readdir
+
+Previously, application code had to set up the d_namlen member if
+the target supported it, involving conditional compilation. After
+this change, glob will use the length of the string in d_name instead
+of d_namlen to determine the file name length. All glibc targets
+provide the d_type and d_ino members, and setting them as needed for
+gl_readdir is straightforward.
+
+Changing the behavior with regards to d_ino is left to a future
+cleanup.
+
+---
+
+--- a/posix/bug-glob2.c
++++ b/posix/bug-glob2.c
+@@ -194,7 +194,7 @@
+ return NULL;
+ }
+
+- dir->d.d_ino = dir->idx;
++ dir->d.d_ino = 1; /* glob should not skip this entry. */
+
+ #ifdef _DIRENT_HAVE_D_TYPE
+ dir->d.d_type = filesystem[dir->idx].type;
+--- a/posix/glob.c
++++ b/posix/glob.c
+@@ -56,10 +56,8 @@
+
+ #if defined HAVE_DIRENT_H || defined __GNU_LIBRARY__
+ # include <dirent.h>
+-# define NAMLEN(dirent) strlen((dirent)->d_name)
+ #else
+ # define dirent direct
+-# define NAMLEN(dirent) (dirent)->d_namlen
+ # ifdef HAVE_SYS_NDIR_H
+ # include <sys/ndir.h>
+ # endif
+@@ -75,12 +73,6 @@
+ #endif
+
+
+-/* In GNU systems, <dirent.h> defines this macro for us. */
+-#ifdef _D_NAMLEN
+-# undef NAMLEN
+-# define NAMLEN(d) _D_NAMLEN(d)
+-#endif
+-
+ /* When used in the GNU libc the symbol _DIRENT_HAVE_D_TYPE is available
+ if the `d_type' member for `struct dirent' is available.
+ HAVE_STRUCT_DIRENT_D_TYPE plays the same role in GNULIB. */
+@@ -104,12 +96,6 @@
+
+ /* If the system has the `struct dirent64' type we use it internally. */
+ #if defined _LIBC && !defined COMPILE_GLOB64
+-# if defined HAVE_DIRENT_H || defined __GNU_LIBRARY__
+-# define CONVERT_D_NAMLEN(d64, d32)
+-# else
+-# define CONVERT_D_NAMLEN(d64, d32) \
+- (d64)->d_namlen = (d32)->d_namlen;
+-# endif
+
+ # if (defined POSIX || defined WINDOWS32) && !defined __GNU_LIBRARY__
+ # define CONVERT_D_INO(d64, d32)
+@@ -126,8 +112,7 @@
+ # endif
+
+ # define CONVERT_DIRENT_DIRENT64(d64, d32) \
+- memcpy ((d64)->d_name, (d32)->d_name, NAMLEN (d32) + 1); \
+- CONVERT_D_NAMLEN (d64, d32) \
++ strcpy ((d64)->d_name, (d32)->d_name); \
+ CONVERT_D_INO (d64, d32) \
+ CONVERT_D_TYPE (d64, d32)
+ #endif
+@@ -1546,7 +1531,6 @@
+ while (1)
+ {
+ const char *name;
+- size_t len;
+ #if defined _LIBC && !defined COMPILE_GLOB64
+ struct dirent64 *d;
+ union
+@@ -1614,12 +1598,10 @@
+ names = newnames;
+ cur = 0;
+ }
+- len = NAMLEN (d);
+- names->name[cur] = (char *) malloc (len + 1);
++ names->name[cur] = strdup (d->d_name);
+ if (names->name[cur] == NULL)
+ goto memory_error;
+- *((char *) mempcpy (names->name[cur++], name, len))
+- = '\0';
++ ++cur;
+ ++nfound;
+ }
+ }
+--- a/posix/tst-gnuglob.c
++++ b/posix/tst-gnuglob.c
+@@ -212,7 +212,7 @@
+ return NULL;
+ }
+
+- dir->d.d_ino = dir->idx;
++ dir->d.d_ino = 1; /* glob should not skip this entry. */
+
+ #ifdef _DIRENT_HAVE_D_TYPE
+ dir->d.d_type = filesystem[dir->idx].type;
Attachment:
signature.asc
Description: PGP signature