wok-4.x diff glibc/stuff/patches/glibc-2.22-CVE-2016-3706.patch @ rev 12476
Up glibc (2.22) with CVE patchs
author | Stanislas Leduc <shann@slitaz.org> |
---|---|
date | Wed Mar 15 11:41:38 2023 +0000 (14 months ago) |
parents | |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/glibc/stuff/patches/glibc-2.22-CVE-2016-3706.patch Wed Mar 15 11:41:38 2023 +0000 1.3 @@ -0,0 +1,182 @@ 1.4 +From 4ab2ab03d4351914ee53248dc5aef4a8c88ff8b9 Mon Sep 17 00:00:00 2001 1.5 +From: Florian Weimer <fweimer@redhat.com> 1.6 +Date: Fri, 29 Apr 2016 10:35:34 +0200 1.7 +Subject: [PATCH] CVE-2016-3706: getaddrinfo: stack overflow in hostent 1.8 + conversion [BZ #20010] 1.9 + 1.10 +When converting a struct hostent response to struct gaih_addrtuple, the 1.11 +gethosts macro (which is called from gaih_inet) used alloca, without 1.12 +malloc fallback for large responses. This commit changes this code to 1.13 +use calloc unconditionally. 1.14 + 1.15 +This commit also consolidated a second hostent-to-gaih_addrtuple 1.16 +conversion loop (in gaih_inet) to use the new conversion function. 1.17 + 1.18 +diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c 1.19 +index 1ef3f20..fed2d3b 100644 1.20 +--- a/sysdeps/posix/getaddrinfo.c 1.21 ++++ b/sysdeps/posix/getaddrinfo.c 1.22 +@@ -168,9 +168,58 @@ gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp, 1.23 + return 0; 1.24 + } 1.25 + 1.26 ++/* Convert struct hostent to a list of struct gaih_addrtuple objects. 1.27 ++ h_name is not copied, and the struct hostent object must not be 1.28 ++ deallocated prematurely. *RESULT must be NULL or a pointer to an 1.29 ++ object allocated using malloc, which is freed. */ 1.30 ++static bool 1.31 ++convert_hostent_to_gaih_addrtuple (const struct addrinfo *req, 1.32 ++ int family, 1.33 ++ struct hostent *h, 1.34 ++ struct gaih_addrtuple **result) 1.35 ++{ 1.36 ++ free (*result); 1.37 ++ *result = NULL; 1.38 ++ 1.39 ++ /* Count the number of addresses in h->h_addr_list. */ 1.40 ++ size_t count = 0; 1.41 ++ for (char **p = h->h_addr_list; *p != NULL; ++p) 1.42 ++ ++count; 1.43 ++ 1.44 ++ /* Report no data if no addresses are available, or if the incoming 1.45 ++ address size is larger than what we can store. */ 1.46 ++ if (count == 0 || h->h_length > sizeof (((struct gaih_addrtuple) {}).addr)) 1.47 ++ return true; 1.48 ++ 1.49 ++ struct gaih_addrtuple *array = calloc (count, sizeof (*array)); 1.50 ++ if (array == NULL) 1.51 ++ return false; 1.52 ++ 1.53 ++ for (size_t i = 0; i < count; ++i) 1.54 ++ { 1.55 ++ if (family == AF_INET && req->ai_family == AF_INET6) 1.56 ++ { 1.57 ++ /* Perform address mapping. */ 1.58 ++ array[i].family = AF_INET6; 1.59 ++ memcpy(array[i].addr + 3, h->h_addr_list[i], sizeof (uint32_t)); 1.60 ++ array[i].addr[2] = htonl (0xffff); 1.61 ++ } 1.62 ++ else 1.63 ++ { 1.64 ++ array[i].family = family; 1.65 ++ memcpy (array[i].addr, h->h_addr_list[i], h->h_length); 1.66 ++ } 1.67 ++ array[i].next = array + i + 1; 1.68 ++ } 1.69 ++ array[0].name = h->h_name; 1.70 ++ array[count - 1].next = NULL; 1.71 ++ 1.72 ++ *result = array; 1.73 ++ return true; 1.74 ++} 1.75 ++ 1.76 + #define gethosts(_family, _type) \ 1.77 + { \ 1.78 +- int i; \ 1.79 + int herrno; \ 1.80 + struct hostent th; \ 1.81 + struct hostent *h; \ 1.82 +@@ -219,36 +268,23 @@ gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp, 1.83 + } \ 1.84 + else if (h != NULL) \ 1.85 + { \ 1.86 +- for (i = 0; h->h_addr_list[i]; i++) \ 1.87 ++ /* Make sure that addrmem can be freed. */ \ 1.88 ++ if (!malloc_addrmem) \ 1.89 ++ addrmem = NULL; \ 1.90 ++ if (!convert_hostent_to_gaih_addrtuple (req, _family,h, &addrmem)) \ 1.91 + { \ 1.92 +- if (*pat == NULL) \ 1.93 +- { \ 1.94 +- *pat = __alloca (sizeof (struct gaih_addrtuple)); \ 1.95 +- (*pat)->scopeid = 0; \ 1.96 +- } \ 1.97 +- uint32_t *addr = (*pat)->addr; \ 1.98 +- (*pat)->next = NULL; \ 1.99 +- (*pat)->name = i == 0 ? strdupa (h->h_name) : NULL; \ 1.100 +- if (_family == AF_INET && req->ai_family == AF_INET6) \ 1.101 +- { \ 1.102 +- (*pat)->family = AF_INET6; \ 1.103 +- addr[3] = *(uint32_t *) h->h_addr_list[i]; \ 1.104 +- addr[2] = htonl (0xffff); \ 1.105 +- addr[1] = 0; \ 1.106 +- addr[0] = 0; \ 1.107 +- } \ 1.108 +- else \ 1.109 +- { \ 1.110 +- (*pat)->family = _family; \ 1.111 +- memcpy (addr, h->h_addr_list[i], sizeof(_type)); \ 1.112 +- } \ 1.113 +- pat = &((*pat)->next); \ 1.114 ++ _res.options |= old_res_options & RES_USE_INET6; \ 1.115 ++ result = -EAI_SYSTEM; \ 1.116 ++ goto free_and_return; \ 1.117 + } \ 1.118 ++ *pat = addrmem; \ 1.119 ++ /* The conversion uses malloc unconditionally. */ \ 1.120 ++ malloc_addrmem = true; \ 1.121 + \ 1.122 + if (localcanon != NULL && canon == NULL) \ 1.123 + canon = strdupa (localcanon); \ 1.124 + \ 1.125 +- if (_family == AF_INET6 && i > 0) \ 1.126 ++ if (_family == AF_INET6 && *pat != NULL) \ 1.127 + got_ipv6 = true; \ 1.128 + } \ 1.129 + } 1.130 +@@ -612,44 +648,16 @@ gaih_inet (const char *name, const struct gaih_service *service, 1.131 + { 1.132 + if (h != NULL) 1.133 + { 1.134 +- int i; 1.135 +- /* We found data, count the number of addresses. */ 1.136 +- for (i = 0; h->h_addr_list[i]; ++i) 1.137 +- ; 1.138 +- if (i > 0 && *pat != NULL) 1.139 +- --i; 1.140 +- 1.141 +- if (__libc_use_alloca (alloca_used 1.142 +- + i * sizeof (struct gaih_addrtuple))) 1.143 +- addrmem = alloca_account (i * sizeof (struct gaih_addrtuple), 1.144 +- alloca_used); 1.145 +- else 1.146 +- { 1.147 +- addrmem = malloc (i 1.148 +- * sizeof (struct gaih_addrtuple)); 1.149 +- if (addrmem == NULL) 1.150 +- { 1.151 +- result = -EAI_MEMORY; 1.152 +- goto free_and_return; 1.153 +- } 1.154 +- malloc_addrmem = true; 1.155 +- } 1.156 +- 1.157 +- /* Now convert it into the list. */ 1.158 +- struct gaih_addrtuple *addrfree = addrmem; 1.159 +- for (i = 0; h->h_addr_list[i]; ++i) 1.160 ++ /* We found data, convert it. */ 1.161 ++ if (!convert_hostent_to_gaih_addrtuple 1.162 ++ (req, AF_INET, h, &addrmem)) 1.163 + { 1.164 +- if (*pat == NULL) 1.165 +- { 1.166 +- *pat = addrfree++; 1.167 +- (*pat)->scopeid = 0; 1.168 +- } 1.169 +- (*pat)->next = NULL; 1.170 +- (*pat)->family = AF_INET; 1.171 +- memcpy ((*pat)->addr, h->h_addr_list[i], 1.172 +- h->h_length); 1.173 +- pat = &((*pat)->next); 1.174 ++ result = -EAI_MEMORY; 1.175 ++ goto free_and_return; 1.176 + } 1.177 ++ *pat = addrmem; 1.178 ++ /* The conversion uses malloc unconditionally. */ 1.179 ++ malloc_addrmem = true; 1.180 + } 1.181 + } 1.182 + else 1.183 +-- 1.184 +2.9.3 1.185 +