diff options
Diffstat (limited to 'gnu/packages/patches/glibc-CVE-2016-3706.patch')
-rw-r--r-- | gnu/packages/patches/glibc-CVE-2016-3706.patch | 188 |
1 files changed, 0 insertions, 188 deletions
diff --git a/gnu/packages/patches/glibc-CVE-2016-3706.patch b/gnu/packages/patches/glibc-CVE-2016-3706.patch deleted file mode 100644 index 617242df24..0000000000 --- a/gnu/packages/patches/glibc-CVE-2016-3706.patch +++ /dev/null @@ -1,188 +0,0 @@ -From 1a8a7c12950a0026a3c406a7cb1608f96aa1460e Mon Sep 17 00:00:00 2001 -From: Florian Weimer <fweimer@redhat.com> -Date: Fri, 29 Apr 2016 10:35:34 +0200 -Subject: [PATCH] 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) ---- - ChangeLog | 10 ++++ - sysdeps/posix/getaddrinfo.c | 130 +++++++++++++++++++++++--------------------- - 2 files changed, 79 insertions(+), 61 deletions(-) - -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 --- -2.9.3 - |