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