- Removed patches that were merged upstream - Removed --localdir from configureFlags as according to https://sourceware.org/bugzilla/show_bug.cgi?id=14259 it was unused beforewip/yesman
parent
081ac25dc6
commit
9744c7768d
@ -1,35 +0,0 @@ |
||||
commit 146b58d11fddbef15b888906e3be4f33900c416f
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Tue Mar 29 12:57:56 2016 +0200
|
||||
|
||||
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.
|
||||
|
||||
(cherry picked from commit 317b199b4aff8cfa27f2302ab404d2bb5032b9a4)
|
||||
(cherry picked from commit 883dceebc8f11921a9890211a4e202e5be17562f)
|
||||
|
||||
diff --git a/resolv/nss_dns/dns-network.c b/resolv/nss_dns/dns-network.c
|
||||
index 2eb2f67..8f301a7 100644
|
||||
--- a/resolv/nss_dns/dns-network.c
|
||||
+++ b/resolv/nss_dns/dns-network.c
|
||||
@@ -118,17 +118,14 @@ _nss_dns_getnetbyname_r (const char *name, struct netent *result,
|
||||
} 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)
|
||||
{
|
@ -1,181 +0,0 @@ |
||||
commit 1a8a7c12950a0026a3c406a7cb1608f96aa1460e
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri Apr 29 10:35:34 2016 +0200
|
||||
|
||||
CVE-2016-3706: getaddrinfo: stack overflow in hostent conversion [BZ #20010]
|
||||
|
||||
When converting a struct hostent response to struct gaih_addrtuple, the
|
||||
gethosts macro (which is called from gaih_inet) used alloca, without
|
||||
malloc fallback for large responses. This commit changes this code to
|
||||
use calloc unconditionally.
|
||||
|
||||
This commit also consolidated a second hostent-to-gaih_addrtuple
|
||||
conversion loop (in gaih_inet) to use the new conversion function.
|
||||
|
||||
(cherry picked from commit 4ab2ab03d4351914ee53248dc5aef4a8c88ff8b9)
|
||||
|
||||
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
|
||||
index 1ef3f20..fed2d3b 100644
|
||||
--- a/sysdeps/posix/getaddrinfo.c
|
||||
+++ b/sysdeps/posix/getaddrinfo.c
|
||||
@@ -168,9 +168,58 @@ gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
|
||||
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; \
|
||||
@@ -219,36 +268,23 @@ gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
|
||||
} \
|
||||
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; \
|
||||
} \
|
||||
}
|
||||
@@ -612,44 +648,16 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||
{
|
||||
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
|
||||
- {
|
||||
- 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)
|
||||
+ /* We found data, convert it. */
|
||||
+ if (!convert_hostent_to_gaih_addrtuple
|
||||
+ (req, AF_INET, h, &addrmem))
|
||||
{
|
||||
- if (*pat == NULL)
|
||||
- {
|
||||
- *pat = addrfree++;
|
||||
- (*pat)->scopeid = 0;
|
||||
- }
|
||||
- (*pat)->next = NULL;
|
||||
- (*pat)->family = AF_INET;
|
||||
- memcpy ((*pat)->addr, h->h_addr_list[i],
|
||||
- h->h_length);
|
||||
- pat = &((*pat)->next);
|
||||
+ result = -EAI_MEMORY;
|
||||
+ goto free_and_return;
|
||||
}
|
||||
+ *pat = addrmem;
|
||||
+ /* The conversion uses malloc unconditionally. */
|
||||
+ malloc_addrmem = true;
|
||||
}
|
||||
}
|
||||
else
|
@ -1,36 +0,0 @@ |
||||
--- a/stdlib/setenv.c 2016-05-30 11:09:14.487180254 +0000
|
||||
+++ b/stdlib/setenv.c 2016-05-30 11:08:25.560390748 +0000
|
||||
@@ -277,6 +277,7 @@
|
||||
|
||||
ep = __environ;
|
||||
if (ep != NULL)
|
||||
+ {
|
||||
while (*ep != NULL)
|
||||
if (!strncmp (*ep, name, len) && (*ep)[len] == '=')
|
||||
{
|
||||
@@ -290,6 +291,7 @@
|
||||
}
|
||||
else
|
||||
++ep;
|
||||
+ }
|
||||
|
||||
UNLOCK;
|
||||
|
||||
--- a/nis/nis_call.c 2016-05-30 08:05:59.359855696 -0700
|
||||
+++ b/nis/nis_call.c 2016-05-30 08:05:55.679873221 -0700
|
||||
@@ -680,6 +680,7 @@
|
||||
/* Choose which entry should be evicted from the cache. */
|
||||
loc = &nis_server_cache[0];
|
||||
if (*loc != NULL)
|
||||
+ {
|
||||
for (i = 1; i < 16; ++i)
|
||||
if (nis_server_cache[i] == NULL)
|
||||
{
|
||||
@@ -690,6 +691,7 @@
|
||||
|| ((*loc)->uses == nis_server_cache[i]->uses
|
||||
&& (*loc)->expires > nis_server_cache[i]->expires))
|
||||
loc = &nis_server_cache[i];
|
||||
+ }
|
||||
old = *loc;
|
||||
*loc = new;
|
||||
|
@ -1,216 +0,0 @@ |
||||
commit 68302147ee061c69eb447e243ad9a18ef4cfbc4c
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri Apr 29 09:33:07 2016 +0200
|
||||
|
||||
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.
|
||||
|
||||
(cherry picked from commit 137fe72eca6923a00381a3ca9f0e7672c1f85e3f)
|
||||
|
||||
diff --git a/manual/examples/mkdirent.c b/manual/examples/mkdirent.c
|
||||
new file mode 100644
|
||||
index 0000000..f8400f4
|
||||
--- /dev/null
|
||||
+++ b/manual/examples/mkdirent.c
|
||||
@@ -0,0 +1,42 @@
|
||||
+/* Example for creating a struct dirent object for use with glob.
|
||||
+ Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
+
|
||||
+ This program is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU General Public License
|
||||
+ as published by the Free Software Foundation; either version 2
|
||||
+ of the License, or (at your option) any later version.
|
||||
+
|
||||
+ This program 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 General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU General Public License
|
||||
+ along with this program; if not, if not, see <http://www.gnu.org/licenses/>.
|
||||
+*/
|
||||
+
|
||||
+#include <dirent.h>
|
||||
+#include <errno.h>
|
||||
+#include <stddef.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+
|
||||
+struct dirent *
|
||||
+mkdirent (const char *name)
|
||||
+{
|
||||
+ size_t dirent_size = offsetof (struct dirent, d_name) + 1;
|
||||
+ size_t name_length = strlen (name);
|
||||
+ size_t total_size = dirent_size + name_length;
|
||||
+ if (total_size < dirent_size)
|
||||
+ {
|
||||
+ errno = ENOMEM;
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ struct dirent *result = malloc (total_size);
|
||||
+ if (result == NULL)
|
||||
+ return NULL;
|
||||
+ result->d_type = DT_UNKNOWN;
|
||||
+ result->d_ino = 1; /* Do not skip this entry. */
|
||||
+ memcpy (result->d_name, name, name_length + 1);
|
||||
+ return result;
|
||||
+}
|
||||
diff --git a/manual/pattern.texi b/manual/pattern.texi
|
||||
index d1b9275..565e7eb 100644
|
||||
--- a/manual/pattern.texi
|
||||
+++ b/manual/pattern.texi
|
||||
@@ -237,7 +237,44 @@ function used to read the contents of a directory. It is used if the
|
||||
@code{GLOB_ALTDIRFUNC} bit is set in the flag parameter. The type of
|
||||
this field is @w{@code{struct dirent *(*) (void *)}}.
|
||||
|
||||
-This is a GNU extension.
|
||||
+An implementation of @code{gl_readdir} needs to initialize the following
|
||||
+members of the @code{struct dirent} object:
|
||||
+
|
||||
+@table @code
|
||||
+@item d_type
|
||||
+This member should be set to the file type of the entry if it is known.
|
||||
+Otherwise, the value @code{DT_UNKNOWN} can be used. The @code{glob}
|
||||
+function may use the specified file type to avoid callbacks in cases
|
||||
+where the file type indicates that the data is not required.
|
||||
+
|
||||
+@item d_ino
|
||||
+This member needs to be non-zero, otherwise @code{glob} may skip the
|
||||
+current entry and call the @code{gl_readdir} callback function again to
|
||||
+retrieve another entry.
|
||||
+
|
||||
+@item d_name
|
||||
+This member must be set to the name of the entry. It must be
|
||||
+null-terminated.
|
||||
+@end table
|
||||
+
|
||||
+The example below shows how to allocate a @code{struct dirent} object
|
||||
+containing a given name.
|
||||
+
|
||||
+@smallexample
|
||||
+@include mkdirent.c.texi
|
||||
+@end smallexample
|
||||
+
|
||||
+The @code{glob} function reads the @code{struct dirent} members listed
|
||||
+above and makes a copy of the file name in the @code{d_name} member
|
||||
+immediately after the @code{gl_readdir} callback function returns.
|
||||
+Future invocations of any of the callback functions may dealloacte or
|
||||
+reuse the buffer. It is the responsibility of the caller of the
|
||||
+@code{glob} function to allocate and deallocate the buffer, around the
|
||||
+call to @code{glob} or using the callback functions. For example, an
|
||||
+application could allocate the buffer in the @code{gl_readdir} callback
|
||||
+function, and deallocate it in the @code{gl_closedir} callback function.
|
||||
+
|
||||
+The @code{gl_readdir} member is a GNU extension.
|
||||
|
||||
@item gl_opendir
|
||||
The address of an alternative implementation of the @code{opendir}
|
||||
diff --git a/posix/bug-glob2.c b/posix/bug-glob2.c
|
||||
index ddf5ec9..0fdc5d0 100644
|
||||
--- a/posix/bug-glob2.c
|
||||
+++ b/posix/bug-glob2.c
|
||||
@@ -193,7 +193,7 @@ my_readdir (void *gdir)
|
||||
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;
|
||||
diff --git a/posix/glob.c b/posix/glob.c
|
||||
index 0c04c3c..9ae76ac 100644
|
||||
--- a/posix/glob.c
|
||||
+++ b/posix/glob.c
|
||||
@@ -57,10 +57,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
|
||||
@@ -76,12 +74,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. */
|
||||
@@ -105,12 +97,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)
|
||||
@@ -127,8 +113,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
|
||||
@@ -1554,7 +1539,6 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
|
||||
while (1)
|
||||
{
|
||||
const char *name;
|
||||
- size_t len;
|
||||
#if defined _LIBC && !defined COMPILE_GLOB64
|
||||
struct dirent64 *d;
|
||||
union
|
||||
@@ -1622,12 +1606,10 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
|
||||
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;
|
||||
}
|
||||
}
|
||||
diff --git a/posix/tst-gnuglob.c b/posix/tst-gnuglob.c
|
||||
index 992b997..b7b859b 100644
|
||||
--- a/posix/tst-gnuglob.c
|
||||
+++ b/posix/tst-gnuglob.c
|
||||
@@ -211,7 +211,7 @@ my_readdir (void *gdir)
|
||||
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;
|
Loading…
Reference in new issue