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 +