[OE-core] [PATCH][thud] glibc: finish incomplete fix for CVE-2016-10739

akuster808 akuster808 at gmail.com
Sun Dec 8 21:37:12 UTC 2019



On 12/5/19 6:45 AM, Ross Burton wrote:
> Somehow the patch for this CVE only included one of the four required patches.

fails:

Applying patch CVE-2016-10739.patch
patching file resolv/inet_addr.c
patching file resolv/nss_dns/dns-host.c
patching file NEWS
Hunk #1 FAILED at 10.
Hunk #2 succeeded at 18 with fuzz 2 (offset -39 lines).
1 out of 2 hunks FAILED -- rejects in file NEWS
patching file include/arpa/inet.h
patching file nscd/gai.c
patching file nscd/gethstbynm3_r.c
patching file nss/digits_dots.c
patching file resolv/Makefile
patching file resolv/Versions
patching file resolv/inet_addr.c
patching file resolv/res_init.c
patching file resolv/tst-aton.c
patching file resolv/tst-inet_aton_exact.c
patching file resolv/tst-resolv-nondecimal.c
patching file resolv/tst-resolv-trailing.c
patching file sysdeps/posix/getaddrinfo.c
patching file nscd/Makefile
patching file nscd/gai.c
patching file nscd/nscd-inet_addr.c
Patch CVE-2016-10739.patch does not apply (enforce with -f)


https://errors.yoctoproject.org/Errors/Details/296402/
> Signed-off-by: Ross Burton <ross.burton at intel.com>
> ---
>  .../glibc/glibc/CVE-2016-10739.patch          | 932 +++++++++++++++++-
>  1 file changed, 929 insertions(+), 3 deletions(-)
>
> diff --git a/meta/recipes-core/glibc/glibc/CVE-2016-10739.patch b/meta/recipes-core/glibc/glibc/CVE-2016-10739.patch
> index 7eb55d6663d..871627da195 100644
> --- a/meta/recipes-core/glibc/glibc/CVE-2016-10739.patch
> +++ b/meta/recipes-core/glibc/glibc/CVE-2016-10739.patch
> @@ -5,12 +5,12 @@ Signed-off-by: Ross Burton <ross.burton at intel.com>
>  From 8e92ca5dd7a7e38a4dddf1ebc4e1e8f0cb27e4aa Mon Sep 17 00:00:00 2001
>  From: Florian Weimer <fweimer at redhat.com>
>  Date: Mon, 21 Jan 2019 08:59:42 +0100
> -Subject: [PATCH] resolv: Reformat inet_addr, inet_aton to GNU style
> +Subject: [PATCH 1/4] resolv: Reformat inet_addr, inet_aton to GNU style
>  
>  (cherry picked from commit 5e30b8ef0758763effa115634e0ed7d8938e4bc0)
>  ---
>   ChangeLog          |   5 ++
> - resolv/inet_addr.c | 192 ++++++++++++++++++++++++++++-------------------------
> + resolv/inet_addr.c | 192 ++++++++++++++++++++++++---------------------
>   2 files changed, 106 insertions(+), 91 deletions(-)
>  
>  diff --git a/resolv/inet_addr.c b/resolv/inet_addr.c
> @@ -229,4 +229,930 @@ index 022f7ea084..32f58b0e13 100644
>   weak_alias (__inet_aton, inet_aton)
>   libc_hidden_def (__inet_aton)
>  -- 
> -2.11.0
> +2.20.1
> +
> +
> +From 37edf1d3f8ab9adefb61cc466ac52b53114fbd5b Mon Sep 17 00:00:00 2001
> +From: Florian Weimer <fweimer at redhat.com>
> +Date: Mon, 21 Jan 2019 09:26:41 +0100
> +Subject: [PATCH 2/4] resolv: Do not send queries for non-host-names in nss_dns
> + [BZ #24112]
> +
> +Before this commit, nss_dns would send a query which did not contain a
> +host name as the query name (such as invalid\032name.example.com) and
> +then reject the answer in getanswer_r and gaih_getanswer_slice, using
> +a check based on res_hnok.  With this commit, no query is sent, and a
> +host-not-found error is returned to NSS without network interaction.
> +
> +(cherry picked from commit 6ca53a2453598804a2559a548a08424fca96434a)
> +---
> + ChangeLog                 |  9 +++++++++
> + resolv/nss_dns/dns-host.c | 24 ++++++++++++++++++++++--
> + 2 files changed, 31 insertions(+), 2 deletions(-)
> +
> +diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
> +index 5dc2829cd1..99c3b61e1c 100644
> +--- a/resolv/nss_dns/dns-host.c
> ++++ b/resolv/nss_dns/dns-host.c
> +@@ -274,11 +274,26 @@ gethostbyname3_context (struct resolv_context *ctx,
> +   return status;
> + }
> + 
> ++/* Verify that the name looks like a host name.  There is no point in
> ++   sending a query which will not produce a usable name in the
> ++   response.  */
> ++static enum nss_status
> ++check_name (const char *name, int *h_errnop)
> ++{
> ++  if (res_hnok (name))
> ++    return NSS_STATUS_SUCCESS;
> ++  *h_errnop = HOST_NOT_FOUND;
> ++  return NSS_STATUS_NOTFOUND;
> ++}
> ++
> + enum nss_status
> + _nss_dns_gethostbyname2_r (const char *name, int af, struct hostent *result,
> + 			   char *buffer, size_t buflen, int *errnop,
> + 			   int *h_errnop)
> + {
> ++  enum nss_status status = check_name (name, h_errnop);
> ++  if (status != NSS_STATUS_SUCCESS)
> ++    return status;
> +   return _nss_dns_gethostbyname3_r (name, af, result, buffer, buflen, errnop,
> + 				    h_errnop, NULL, NULL);
> + }
> +@@ -289,6 +304,9 @@ _nss_dns_gethostbyname_r (const char *name, struct hostent *result,
> + 			  char *buffer, size_t buflen, int *errnop,
> + 			  int *h_errnop)
> + {
> ++  enum nss_status status = check_name (name, h_errnop);
> ++  if (status != NSS_STATUS_SUCCESS)
> ++    return status;
> +   struct resolv_context *ctx = __resolv_context_get ();
> +   if (ctx == NULL)
> +     {
> +@@ -296,7 +314,7 @@ _nss_dns_gethostbyname_r (const char *name, struct hostent *result,
> +       *h_errnop = NETDB_INTERNAL;
> +       return NSS_STATUS_UNAVAIL;
> +     }
> +-  enum nss_status status = NSS_STATUS_NOTFOUND;
> ++  status = NSS_STATUS_NOTFOUND;
> +   if (res_use_inet6 ())
> +     status = gethostbyname3_context (ctx, name, AF_INET6, result, buffer,
> + 				     buflen, errnop, h_errnop, NULL, NULL);
> +@@ -313,6 +331,9 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
> + 			   char *buffer, size_t buflen, int *errnop,
> + 			   int *herrnop, int32_t *ttlp)
> + {
> ++  enum nss_status status = check_name (name, herrnop);
> ++  if (status != NSS_STATUS_SUCCESS)
> ++    return status;
> +   struct resolv_context *ctx = __resolv_context_get ();
> +   if (ctx == NULL)
> +     {
> +@@ -347,7 +368,6 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
> +   int ans2p_malloced = 0;
> + 
> +   int olderr = errno;
> +-  enum nss_status status;
> +   int n = __res_context_search (ctx, name, C_IN, T_QUERY_A_AND_AAAA,
> + 				host_buffer.buf->buf, 2048, &host_buffer.ptr,
> + 				&ans2p, &nans2p, &resplen2, &ans2p_malloced);
> +-- 
> +2.20.1
> +
> +
> +From 2373941bd73cb288c8a42a33e23e7f7bb81151e7 Mon Sep 17 00:00:00 2001
> +From: Florian Weimer <fweimer at redhat.com>
> +Date: Mon, 21 Jan 2019 21:26:03 +0100
> +Subject: [PATCH 3/4] CVE-2016-10739: getaddrinfo: Fully parse IPv4 address
> + strings [BZ #20018]
> +
> +The IPv4 address parser in the getaddrinfo function is changed so that
> +it does not ignore trailing whitespace and all characters after it.
> +For backwards compatibility, the getaddrinfo function still recognizes
> +legacy name syntax, such as 192.000.002.010 interpreted as 192.0.2.8
> +(octal).
> +
> +This commit does not change the behavior of inet_addr and inet_aton.
> +gethostbyname already had additional sanity checks (but is switched
> +over to the new __inet_aton_exact function for completeness as well).
> +
> +To avoid sending the problematic query names over DNS, commit
> +6ca53a2453598804a2559a548a08424fca96434a ("resolv: Do not send queries
> +for non-host-names in nss_dns [BZ #24112]") is needed.
> +
> +(cherry picked from commit 108bc4049f8ae82710aec26a92ffdb4b439c83fd)
> +---
> + ChangeLog                      |  33 ++++++++
> + NEWS                           |   4 +
> + include/arpa/inet.h            |   6 +-
> + nscd/gai.c                     |   1 -
> + nscd/gethstbynm3_r.c           |   2 -
> + nss/digits_dots.c              |   3 +-
> + resolv/Makefile                |   7 ++
> + resolv/Versions                |   1 +
> + resolv/inet_addr.c             |  62 ++++++++++-----
> + resolv/res_init.c              |  17 ++--
> + resolv/tst-aton.c              |  35 +++++++--
> + resolv/tst-inet_aton_exact.c   |  47 +++++++++++
> + resolv/tst-resolv-nondecimal.c | 139 +++++++++++++++++++++++++++++++++
> + resolv/tst-resolv-trailing.c   | 136 ++++++++++++++++++++++++++++++++
> + sysdeps/posix/getaddrinfo.c    |   2 +-
> + 15 files changed, 455 insertions(+), 40 deletions(-)
> + create mode 100644 resolv/tst-inet_aton_exact.c
> + create mode 100644 resolv/tst-resolv-nondecimal.c
> + create mode 100644 resolv/tst-resolv-trailing.c
> +
> +diff --git a/NEWS b/NEWS
> +index 0e58ca8904..a1af88e193 100644
> +--- a/NEWS
> ++++ b/NEWS
> +@@ -10,6 +10,7 @@ Version 2.28.1
> + The following bugs are resolved with this release:
> + 
> +   [19444] build failures with -O1 due to -Wmaybe-uninitialized
> ++  [20018] getaddrinfo should reject IP addresses with trailing characters
> +   [20209] localedata: Spelling mistake for Sunday in Greenlandic kl_GL
> +   [22927] libanl: properly cleanup if first helper thread creation failed
> +   [23400] stdlib/test-bz22786.c creates temporary files in glibc source tree
> +@@ -57,6 +58,9 @@ Security related changes:
> +   memcmp gave the wrong result since it treated the size argument as
> +   zero.  Reported by H.J. Lu.
> + 
> ++  CVE-2016-10739: The getaddrinfo function could successfully parse IPv4
> ++  addresses with arbitrary trailing characters, potentially leading to data
> ++  or command injection issues in applications.
> + 
> + Version 2.28
> + 
> +diff --git a/include/arpa/inet.h b/include/arpa/inet.h
> +index c3f28f2baa..19aec74275 100644
> +--- a/include/arpa/inet.h
> ++++ b/include/arpa/inet.h
> +@@ -1,10 +1,10 @@
> + #include <inet/arpa/inet.h>
> + 
> + #ifndef _ISOMAC
> +-extern int __inet_aton (const char *__cp, struct in_addr *__inp);
> +-libc_hidden_proto (__inet_aton)
> ++/* Variant of inet_aton which rejects trailing garbage.  */
> ++extern int __inet_aton_exact (const char *__cp, struct in_addr *__inp);
> ++libc_hidden_proto (__inet_aton_exact)
> + 
> +-libc_hidden_proto (inet_aton)
> + libc_hidden_proto (inet_ntop)
> + libc_hidden_proto (inet_pton)
> + extern __typeof (inet_pton) __inet_pton;
> +diff --git a/nscd/gai.c b/nscd/gai.c
> +index 24bdfee1db..f57f396f57 100644
> +--- a/nscd/gai.c
> ++++ b/nscd/gai.c
> +@@ -19,7 +19,6 @@
> + 
> + /* This file uses the getaddrinfo code but it compiles it without NSCD
> +    support.  We just need a few symbol renames.  */
> +-#define __inet_aton inet_aton
> + #define __ioctl ioctl
> + #define __getsockname getsockname
> + #define __socket socket
> +diff --git a/nscd/gethstbynm3_r.c b/nscd/gethstbynm3_r.c
> +index 7beb9dce9f..f792c4fcd0 100644
> +--- a/nscd/gethstbynm3_r.c
> ++++ b/nscd/gethstbynm3_r.c
> +@@ -38,8 +38,6 @@
> + #define HAVE_LOOKUP_BUFFER	1
> + #define HAVE_AF			1
> + 
> +-#define __inet_aton inet_aton
> +-
> + /* We are nscd, so we don't want to be talking to ourselves.  */
> + #undef	USE_NSCD
> + 
> +diff --git a/nss/digits_dots.c b/nss/digits_dots.c
> +index 39bff38865..5441bce16e 100644
> +--- a/nss/digits_dots.c
> ++++ b/nss/digits_dots.c
> +@@ -29,7 +29,6 @@
> + #include "nsswitch.h"
> + 
> + #ifdef USE_NSCD
> +-# define inet_aton __inet_aton
> + # include <nscd/nscd_proto.h>
> + #endif
> + 
> +@@ -160,7 +159,7 @@ __nss_hostname_digits_dots_context (struct resolv_context *ctx,
> + 		     255.255.255.255?  The test below will succeed
> + 		     spuriously... ???  */
> + 		  if (af == AF_INET)
> +-		    ok = __inet_aton (name, (struct in_addr *) host_addr);
> ++		    ok = __inet_aton_exact (name, (struct in_addr *) host_addr);
> + 		  else
> + 		    {
> + 		      assert (af == AF_INET6);
> +diff --git a/resolv/Makefile b/resolv/Makefile
> +index ea395ac3eb..d36eedd34a 100644
> +--- a/resolv/Makefile
> ++++ b/resolv/Makefile
> +@@ -34,6 +34,9 @@ routines := herror inet_addr inet_ntop inet_pton nsap_addr res_init \
> + tests = tst-aton tst-leaks tst-inet_ntop
> + xtests = tst-leaks2
> + 
> ++tests-internal += tst-inet_aton_exact
> ++
> ++
> + generate := mtrace-tst-leaks.out tst-leaks.mtrace tst-leaks2.mtrace
> + 
> + extra-libs := libresolv libnss_dns
> +@@ -54,8 +57,10 @@ tests += \
> +   tst-resolv-binary \
> +   tst-resolv-edns \
> +   tst-resolv-network \
> ++  tst-resolv-nondecimal \
> +   tst-resolv-res_init-multi \
> +   tst-resolv-search \
> ++  tst-resolv-trailing \
> + 
> + # These tests need libdl.
> + ifeq (yes,$(build-shared))
> +@@ -190,9 +195,11 @@ $(objpfx)tst-resolv-res_init-multi: $(objpfx)libresolv.so \
> +   $(shared-thread-library)
> + $(objpfx)tst-resolv-res_init-thread: $(libdl) $(objpfx)libresolv.so \
> +   $(shared-thread-library)
> ++$(objpfx)tst-resolv-nondecimal: $(objpfx)libresolv.so $(shared-thread-library)
> + $(objpfx)tst-resolv-qtypes: $(objpfx)libresolv.so $(shared-thread-library)
> + $(objpfx)tst-resolv-rotate: $(objpfx)libresolv.so $(shared-thread-library)
> + $(objpfx)tst-resolv-search: $(objpfx)libresolv.so $(shared-thread-library)
> ++$(objpfx)tst-resolv-trailing: $(objpfx)libresolv.so $(shared-thread-library)
> + $(objpfx)tst-resolv-threads: \
> +   $(libdl) $(objpfx)libresolv.so $(shared-thread-library)
> + $(objpfx)tst-resolv-canonname: \
> +diff --git a/resolv/Versions b/resolv/Versions
> +index b05778d965..9a82704af7 100644
> +--- a/resolv/Versions
> ++++ b/resolv/Versions
> +@@ -27,6 +27,7 @@ libc {
> +     __h_errno; __resp;
> + 
> +     __res_iclose;
> ++    __inet_aton_exact;
> +     __inet_pton_length;
> +     __resolv_context_get;
> +     __resolv_context_get_preinit;
> +diff --git a/resolv/inet_addr.c b/resolv/inet_addr.c
> +index 32f58b0e13..41b6166a5b 100644
> +--- a/resolv/inet_addr.c
> ++++ b/resolv/inet_addr.c
> +@@ -96,26 +96,14 @@
> + #include <limits.h>
> + #include <errno.h>
> + 
> +-/* ASCII IPv4 Internet address interpretation routine.  The value
> +-   returned is in network order.  */
> +-in_addr_t
> +-__inet_addr (const char *cp)
> +-{
> +-  struct in_addr val;
> +-
> +-  if (__inet_aton (cp, &val))
> +-    return val.s_addr;
> +-  return INADDR_NONE;
> +-}
> +-weak_alias (__inet_addr, inet_addr)
> +-
> + /* Check whether "cp" is a valid ASCII representation of an IPv4
> +    Internet address and convert it to a binary address.  Returns 1 if
> +    the address is valid, 0 if not.  This replaces inet_addr, the
> +    return value from which cannot distinguish between failure and a
> +-   local broadcast address.  */
> +-int
> +-__inet_aton (const char *cp, struct in_addr *addr)
> ++   local broadcast address.  Write a pointer to the first
> ++   non-converted character to *endp.  */
> ++static int
> ++inet_aton_end (const char *cp, struct in_addr *addr, const char **endp)
> + {
> +   static const in_addr_t max[4] = { 0xffffffff, 0xffffff, 0xffff, 0xff };
> +   in_addr_t val;
> +@@ -180,6 +168,7 @@ __inet_aton (const char *cp, struct in_addr *addr)
> + 
> +   if (addr != NULL)
> +     addr->s_addr = res.word | htonl (val);
> ++  *endp = cp;
> + 
> +   __set_errno (saved_errno);
> +   return 1;
> +@@ -188,6 +177,41 @@ __inet_aton (const char *cp, struct in_addr *addr)
> +   __set_errno (saved_errno);
> +   return 0;
> + }
> +-weak_alias (__inet_aton, inet_aton)
> +-libc_hidden_def (__inet_aton)
> +-libc_hidden_weak (inet_aton)
> ++
> ++int
> ++__inet_aton_exact (const char *cp, struct in_addr *addr)
> ++{
> ++  struct in_addr val;
> ++  const char *endp;
> ++  /* Check that inet_aton_end parsed the entire string.  */
> ++  if (inet_aton_end (cp, &val, &endp) != 0 && *endp == 0)
> ++    {
> ++      *addr = val;
> ++      return 1;
> ++    }
> ++  else
> ++    return 0;
> ++}
> ++libc_hidden_def (__inet_aton_exact)
> ++
> ++/* inet_aton ignores trailing garbage.  */
> ++int
> ++__inet_aton_ignore_trailing (const char *cp, struct in_addr *addr)
> ++{
> ++  const char *endp;
> ++  return  inet_aton_end (cp, addr, &endp);
> ++}
> ++weak_alias (__inet_aton_ignore_trailing, inet_aton)
> ++
> ++/* ASCII IPv4 Internet address interpretation routine.  The value
> ++   returned is in network order.  */
> ++in_addr_t
> ++__inet_addr (const char *cp)
> ++{
> ++  struct in_addr val;
> ++  const char *endp;
> ++  if (inet_aton_end (cp, &val, &endp))
> ++    return val.s_addr;
> ++  return INADDR_NONE;
> ++}
> ++weak_alias (__inet_addr, inet_addr)
> +diff --git a/resolv/res_init.c b/resolv/res_init.c
> +index f5e52cbbb9..94743a252e 100644
> +--- a/resolv/res_init.c
> ++++ b/resolv/res_init.c
> +@@ -399,8 +399,16 @@ res_vinit_1 (FILE *fp, struct resolv_conf_parser *parser)
> +               cp = parser->buffer + sizeof ("nameserver") - 1;
> +               while (*cp == ' ' || *cp == '\t')
> +                 cp++;
> ++
> ++              /* Ignore trailing contents on the name server line.  */
> ++              {
> ++                char *el;
> ++                if ((el = strpbrk (cp, " \t\n")) != NULL)
> ++                  *el = '\0';
> ++              }
> ++
> +               struct sockaddr *sa;
> +-              if ((*cp != '\0') && (*cp != '\n') && __inet_aton (cp, &a))
> ++              if ((*cp != '\0') && (*cp != '\n') && __inet_aton_exact (cp, &a))
> +                 {
> +                   sa = allocate_address_v4 (a, NAMESERVER_PORT);
> +                   if (sa == NULL)
> +@@ -410,9 +418,6 @@ res_vinit_1 (FILE *fp, struct resolv_conf_parser *parser)
> +                 {
> +                   struct in6_addr a6;
> +                   char *el;
> +-
> +-                  if ((el = strpbrk (cp, " \t\n")) != NULL)
> +-                    *el = '\0';
> +                   if ((el = strchr (cp, SCOPE_DELIMITER)) != NULL)
> +                     *el = '\0';
> +                   if ((*cp != '\0') && (__inet_pton (AF_INET6, cp, &a6) > 0))
> +@@ -472,7 +477,7 @@ res_vinit_1 (FILE *fp, struct resolv_conf_parser *parser)
> +                   char separator = *cp;
> +                   *cp = 0;
> +                   struct resolv_sortlist_entry e;
> +-                  if (__inet_aton (net, &a))
> ++                  if (__inet_aton_exact (net, &a))
> +                     {
> +                       e.addr = a;
> +                       if (is_sort_mask (separator))
> +@@ -484,7 +489,7 @@ res_vinit_1 (FILE *fp, struct resolv_conf_parser *parser)
> +                             cp++;
> +                           separator = *cp;
> +                           *cp = 0;
> +-                          if (__inet_aton (net, &a))
> ++                          if (__inet_aton_exact (net, &a))
> +                             e.mask = a.s_addr;
> +                           else
> +                             e.mask = net_mask (e.addr);
> +diff --git a/resolv/tst-aton.c b/resolv/tst-aton.c
> +index 08110a007a..eb734d7758 100644
> +--- a/resolv/tst-aton.c
> ++++ b/resolv/tst-aton.c
> +@@ -1,11 +1,29 @@
> ++/* Test legacy IPv4 text-to-address function inet_aton.
> ++   Copyright (C) 1998-2019 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 <array_length.h>
> + #include <stdio.h>
> + #include <stdint.h>
> + #include <sys/socket.h>
> + #include <netinet/in.h>
> + #include <arpa/inet.h>
> + 
> +-
> +-static struct tests
> ++static const struct tests
> + {
> +   const char *input;
> +   int valid;
> +@@ -16,6 +34,7 @@ static struct tests
> +   { "-1", 0, 0 },
> +   { "256", 1, 0x00000100 },
> +   { "256.", 0, 0 },
> ++  { "255a", 0, 0 },
> +   { "256a", 0, 0 },
> +   { "0x100", 1, 0x00000100 },
> +   { "0200.0x123456", 1, 0x80123456 },
> +@@ -40,7 +59,12 @@ static struct tests
> +   { "1.2.256.4", 0, 0 },
> +   { "1.2.3.0x100", 0, 0 },
> +   { "323543357756889", 0, 0 },
> +-  { "10.1.2.3.4", 0, 0},
> ++  { "10.1.2.3.4", 0, 0 },
> ++  { "192.0.2.1", 1, 0xc0000201 },
> ++  { "192.0.2.2\nX", 1, 0xc0000202 },
> ++  { "192.0.2.3 Y", 1, 0xc0000203 },
> ++  { "192.0.2.3Z", 0, 0 },
> ++  { "192.000.002.010", 1, 0xc0000208 },
> + };
> + 
> + 
> +@@ -50,7 +74,7 @@ do_test (void)
> +   int result = 0;
> +   size_t cnt;
> + 
> +-  for (cnt = 0; cnt < sizeof (tests) / sizeof (tests[0]); ++cnt)
> ++  for (cnt = 0; cnt < array_length (tests); ++cnt)
> +     {
> +       struct in_addr addr;
> + 
> +@@ -73,5 +97,4 @@ do_test (void)
> +   return result;
> + }
> + 
> +-#define TEST_FUNCTION do_test ()
> +-#include "../test-skeleton.c"
> ++#include <support/test-driver.c>
> +diff --git a/resolv/tst-inet_aton_exact.c b/resolv/tst-inet_aton_exact.c
> +new file mode 100644
> +index 0000000000..0fdfa3d6aa
> +--- /dev/null
> ++++ b/resolv/tst-inet_aton_exact.c
> +@@ -0,0 +1,47 @@
> ++/* Test internal legacy IPv4 text-to-address function __inet_aton_exact.
> ++   Copyright (C) 2019 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 <arpa/inet.h>
> ++#include <support/check.h>
> ++
> ++static int
> ++do_test (void)
> ++{
> ++  struct in_addr addr = { };
> ++
> ++  TEST_COMPARE (__inet_aton_exact ("192.0.2.1", &addr), 1);
> ++  TEST_COMPARE (ntohl (addr.s_addr), 0xC0000201);
> ++
> ++  TEST_COMPARE (__inet_aton_exact ("192.000.002.010", &addr), 1);
> ++  TEST_COMPARE (ntohl (addr.s_addr), 0xC0000208);
> ++  TEST_COMPARE (__inet_aton_exact ("0xC0000234", &addr), 1);
> ++  TEST_COMPARE (ntohl (addr.s_addr), 0xC0000234);
> ++
> ++  /* Trailing content is not accepted.  */
> ++  TEST_COMPARE (__inet_aton_exact ("192.0.2.2X", &addr), 0);
> ++  TEST_COMPARE (__inet_aton_exact ("192.0.2.3 Y", &addr), 0);
> ++  TEST_COMPARE (__inet_aton_exact ("192.0.2.4\nZ", &addr), 0);
> ++  TEST_COMPARE (__inet_aton_exact ("192.0.2.5\tT", &addr), 0);
> ++  TEST_COMPARE (__inet_aton_exact ("192.0.2.6 Y", &addr), 0);
> ++  TEST_COMPARE (__inet_aton_exact ("192.0.2.7\n", &addr), 0);
> ++  TEST_COMPARE (__inet_aton_exact ("192.0.2.8\t", &addr), 0);
> ++
> ++  return 0;
> ++}
> ++
> ++#include <support/test-driver.c>
> +diff --git a/resolv/tst-resolv-nondecimal.c b/resolv/tst-resolv-nondecimal.c
> +new file mode 100644
> +index 0000000000..a0df6f332a
> +--- /dev/null
> ++++ b/resolv/tst-resolv-nondecimal.c
> +@@ -0,0 +1,139 @@
> ++/* Test name resolution behavior for octal, hexadecimal IPv4 addresses.
> ++   Copyright (C) 2019 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 <netdb.h>
> ++#include <stdlib.h>
> ++#include <support/check.h>
> ++#include <support/check_nss.h>
> ++#include <support/resolv_test.h>
> ++#include <support/support.h>
> ++
> ++static void
> ++response (const struct resolv_response_context *ctx,
> ++          struct resolv_response_builder *b,
> ++          const char *qname, uint16_t qclass, uint16_t qtype)
> ++{
> ++  /* The tests are not supposed send any DNS queries.  */
> ++  FAIL_EXIT1 ("unexpected DNS query for %s/%d/%d", qname, qclass, qtype);
> ++}
> ++
> ++static void
> ++run_query_addrinfo (const char *query, const char *address)
> ++{
> ++  char *quoted_query = support_quote_string (query);
> ++
> ++  struct addrinfo *ai;
> ++  struct addrinfo hints =
> ++    {
> ++     .ai_socktype = SOCK_STREAM,
> ++     .ai_protocol = IPPROTO_TCP,
> ++    };
> ++
> ++  char *context = xasprintf ("getaddrinfo \"%s\" AF_INET", quoted_query);
> ++  char *expected = xasprintf ("address: STREAM/TCP %s 80\n", address);
> ++  hints.ai_family = AF_INET;
> ++  int ret = getaddrinfo (query, "80", &hints, &ai);
> ++  check_addrinfo (context, ai, ret, expected);
> ++  if (ret == 0)
> ++    freeaddrinfo (ai);
> ++  free (context);
> ++
> ++  context = xasprintf ("getaddrinfo \"%s\" AF_UNSPEC", quoted_query);
> ++  hints.ai_family = AF_UNSPEC;
> ++  ret = getaddrinfo (query, "80", &hints, &ai);
> ++  check_addrinfo (context, ai, ret, expected);
> ++  if (ret == 0)
> ++    freeaddrinfo (ai);
> ++  free (expected);
> ++  free (context);
> ++
> ++  context = xasprintf ("getaddrinfo \"%s\" AF_INET6", quoted_query);
> ++  expected = xasprintf ("flags: AI_V4MAPPED\n"
> ++                        "address: STREAM/TCP ::ffff:%s 80\n",
> ++                        address);
> ++  hints.ai_family = AF_INET6;
> ++  hints.ai_flags = AI_V4MAPPED;
> ++  ret = getaddrinfo (query, "80", &hints, &ai);
> ++  check_addrinfo (context, ai, ret, expected);
> ++  if (ret == 0)
> ++    freeaddrinfo (ai);
> ++  free (expected);
> ++  free (context);
> ++
> ++  free (quoted_query);
> ++}
> ++
> ++static void
> ++run_query (const char *query, const char *address)
> ++{
> ++  char *quoted_query = support_quote_string (query);
> ++  char *context = xasprintf ("gethostbyname (\"%s\")", quoted_query);
> ++  char *expected = xasprintf ("name: %s\n"
> ++                              "address: %s\n", query, address);
> ++  check_hostent (context, gethostbyname (query), expected);
> ++  free (context);
> ++
> ++  context = xasprintf ("gethostbyname_r \"%s\"", quoted_query);
> ++  struct hostent storage;
> ++  char buf[4096];
> ++  struct hostent *e = NULL;
> ++  TEST_COMPARE (gethostbyname_r (query, &storage, buf, sizeof (buf),
> ++                                 &e, &h_errno), 0);
> ++  check_hostent (context, e, expected);
> ++  free (context);
> ++
> ++  context = xasprintf ("gethostbyname2 (\"%s\", AF_INET)", quoted_query);
> ++  check_hostent (context, gethostbyname2 (query, AF_INET), expected);
> ++  free (context);
> ++
> ++  context = xasprintf ("gethostbyname2_r \"%s\" AF_INET", quoted_query);
> ++  e = NULL;
> ++  TEST_COMPARE (gethostbyname2_r (query, AF_INET, &storage, buf, sizeof (buf),
> ++                                  &e, &h_errno), 0);
> ++  check_hostent (context, e, expected);
> ++  free (context);
> ++  free (expected);
> ++
> ++  free (quoted_query);
> ++
> ++  /* The gethostbyname tests are always valid for getaddrinfo, but not
> ++     vice versa.  */
> ++  run_query_addrinfo (query, address);
> ++}
> ++
> ++static int
> ++do_test (void)
> ++{
> ++  struct resolv_test *aux = resolv_test_start
> ++    ((struct resolv_redirect_config)
> ++     {
> ++       .response_callback = response,
> ++     });
> ++
> ++  run_query ("192.000.002.010", "192.0.2.8");
> ++
> ++  /* Hexadecimal numbers are not accepted by gethostbyname.  */
> ++  run_query_addrinfo ("0xc0000210", "192.0.2.16");
> ++  run_query_addrinfo ("192.0x234", "192.0.2.52");
> ++
> ++  resolv_test_end (aux);
> ++
> ++  return 0;
> ++}
> ++
> ++#include <support/test-driver.c>
> +diff --git a/resolv/tst-resolv-trailing.c b/resolv/tst-resolv-trailing.c
> +new file mode 100644
> +index 0000000000..7504bdae57
> +--- /dev/null
> ++++ b/resolv/tst-resolv-trailing.c
> +@@ -0,0 +1,136 @@
> ++/* Test name resolution behavior with trailing characters.
> ++   Copyright (C) 2019 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 <array_length.h>
> ++#include <netdb.h>
> ++#include <support/check.h>
> ++#include <support/check_nss.h>
> ++#include <support/resolv_test.h>
> ++#include <support/support.h>
> ++
> ++static void
> ++response (const struct resolv_response_context *ctx,
> ++          struct resolv_response_builder *b,
> ++          const char *qname, uint16_t qclass, uint16_t qtype)
> ++{
> ++  /* The tests are not supposed send any DNS queries.  */
> ++  FAIL_EXIT1 ("unexpected DNS query for %s/%d/%d", qname, qclass, qtype);
> ++}
> ++
> ++static int
> ++do_test (void)
> ++{
> ++  struct resolv_test *aux = resolv_test_start
> ++    ((struct resolv_redirect_config)
> ++     {
> ++       .response_callback = response,
> ++     });
> ++
> ++  static const char *const queries[] =
> ++    {
> ++     "192.0.2.1 ",
> ++     "192.0.2.2\t",
> ++     "192.0.2.3\n",
> ++     "192.0.2.4 X",
> ++     "192.0.2.5\tY",
> ++     "192.0.2.6\nZ",
> ++     "192.0.2. ",
> ++     "192.0.2.\t",
> ++     "192.0.2.\n",
> ++     "192.0.2. X",
> ++     "192.0.2.\tY",
> ++     "192.0.2.\nZ",
> ++     "2001:db8::1 ",
> ++     "2001:db8::2\t",
> ++     "2001:db8::3\n",
> ++     "2001:db8::4 X",
> ++     "2001:db8::5\tY",
> ++     "2001:db8::6\nZ",
> ++    };
> ++  for (size_t query_idx = 0; query_idx < array_length (queries); ++query_idx)
> ++    {
> ++      const char *query = queries[query_idx];
> ++      struct hostent storage;
> ++      char buf[4096];
> ++      struct hostent *e;
> ++
> ++      h_errno = 0;
> ++      TEST_VERIFY (gethostbyname (query) == NULL);
> ++      TEST_COMPARE (h_errno, HOST_NOT_FOUND);
> ++
> ++      h_errno = 0;
> ++      e = NULL;
> ++      TEST_COMPARE (gethostbyname_r (query, &storage, buf, sizeof (buf),
> ++                                     &e, &h_errno), 0);
> ++      TEST_VERIFY (e == NULL);
> ++      TEST_COMPARE (h_errno, HOST_NOT_FOUND);
> ++
> ++      h_errno = 0;
> ++      TEST_VERIFY (gethostbyname2 (query, AF_INET) == NULL);
> ++      TEST_COMPARE (h_errno, HOST_NOT_FOUND);
> ++
> ++      h_errno = 0;
> ++      e = NULL;
> ++      TEST_COMPARE (gethostbyname2_r (query, AF_INET,
> ++                                      &storage, buf, sizeof (buf),
> ++                                     &e, &h_errno), 0);
> ++      TEST_VERIFY (e == NULL);
> ++      TEST_COMPARE (h_errno, HOST_NOT_FOUND);
> ++
> ++      h_errno = 0;
> ++      TEST_VERIFY (gethostbyname2 (query, AF_INET6) == NULL);
> ++      TEST_COMPARE (h_errno, HOST_NOT_FOUND);
> ++
> ++      h_errno = 0;
> ++      e = NULL;
> ++      TEST_COMPARE (gethostbyname2_r (query, AF_INET6,
> ++                                      &storage, buf, sizeof (buf),
> ++                                     &e, &h_errno), 0);
> ++      TEST_VERIFY (e == NULL);
> ++      TEST_COMPARE (h_errno, HOST_NOT_FOUND);
> ++
> ++      static const int gai_flags[] =
> ++        {
> ++         0,
> ++         AI_ADDRCONFIG,
> ++         AI_NUMERICHOST,
> ++         AI_IDN,
> ++         AI_IDN | AI_NUMERICHOST,
> ++         AI_V4MAPPED,
> ++         AI_V4MAPPED | AI_NUMERICHOST,
> ++        };
> ++      for (size_t gai_flags_idx; gai_flags_idx < array_length (gai_flags);
> ++             ++gai_flags_idx)
> ++        {
> ++          struct addrinfo hints = { .ai_flags = gai_flags[gai_flags_idx], };
> ++          struct addrinfo *ai;
> ++          hints.ai_family = AF_INET;
> ++          TEST_COMPARE (getaddrinfo (query, "80", &hints, &ai), EAI_NONAME);
> ++          hints.ai_family = AF_INET6;
> ++          TEST_COMPARE (getaddrinfo (query, "80", &hints, &ai), EAI_NONAME);
> ++          hints.ai_family = AF_UNSPEC;
> ++          TEST_COMPARE (getaddrinfo (query, "80", &hints, &ai), EAI_NONAME);
> ++        }
> ++    };
> ++
> ++  resolv_test_end (aux);
> ++
> ++  return 0;
> ++}
> ++
> ++#include <support/test-driver.c>
> +diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
> +index 553833d1f2..c91b281e31 100644
> +--- a/sysdeps/posix/getaddrinfo.c
> ++++ b/sysdeps/posix/getaddrinfo.c
> +@@ -488,7 +488,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
> + 	  malloc_name = true;
> + 	}
> + 
> +-      if (__inet_aton (name, (struct in_addr *) at->addr) != 0)
> ++      if (__inet_aton_exact (name, (struct in_addr *) at->addr) != 0)
> + 	{
> + 	  if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
> + 	    at->family = AF_INET;
> +-- 
> +2.20.1
> +
> +
> +From c533244b8e00ae701583ec50aeb43377d292452d Mon Sep 17 00:00:00 2001
> +From: Florian Weimer <fweimer at redhat.com>
> +Date: Mon, 4 Feb 2019 20:07:18 +0100
> +Subject: [PATCH 4/4] nscd: Do not use __inet_aton_exact at GLIBC_PRIVATE [BZ
> + #20018]
> +
> +This commit avoids referencing the __inet_aton_exact at GLIBC_PRIVATE
> +symbol from nscd.  In master, the separately-compiled getaddrinfo
> +implementation in nscd needs it, however such an internal ABI change
> +is not desirable on a release branch if it can be avoided.
> +---
> + ChangeLog             | 10 ++++++++++
> + nscd/Makefile         |  2 +-
> + nscd/gai.c            |  6 ++++++
> + nscd/nscd-inet_addr.c | 32 ++++++++++++++++++++++++++++++++
> + 4 files changed, 49 insertions(+), 1 deletion(-)
> + create mode 100644 nscd/nscd-inet_addr.c
> +
> +diff --git a/nscd/Makefile b/nscd/Makefile
> +index b713a84c49..eb23c01a39 100644
> +--- a/nscd/Makefile
> ++++ b/nscd/Makefile
> +@@ -36,7 +36,7 @@ nscd-modules := nscd connections pwdcache getpwnam_r getpwuid_r grpcache \
> + 		getsrvbynm_r getsrvbypt_r servicescache \
> + 		dbg_log nscd_conf nscd_stat cache mem nscd_setup_thread \
> + 		xmalloc xstrdup aicache initgrcache gai res_hconf \
> +-		netgroupcache
> ++		netgroupcache nscd-inet_addr
> + 
> + ifeq ($(build-nscd)$(have-thread-library),yesyes)
> + 
> +diff --git a/nscd/gai.c b/nscd/gai.c
> +index f57f396f57..68a4abd30e 100644
> +--- a/nscd/gai.c
> ++++ b/nscd/gai.c
> +@@ -33,6 +33,12 @@
> + #define __getifaddrs getifaddrs
> + #define __freeifaddrs freeifaddrs
> + 
> ++/* We do not want to export __inet_aton_exact.  Get the prototype and
> ++   change its visibility to hidden.  */
> ++#include <arpa/inet.h>
> ++__typeof__ (__inet_aton_exact) __inet_aton_exact
> ++  __attribute__ ((visibility ("hidden")));
> ++
> + /* We are nscd, so we don't want to be talking to ourselves.  */
> + #undef  USE_NSCD
> + 
> +diff --git a/nscd/nscd-inet_addr.c b/nscd/nscd-inet_addr.c
> +new file mode 100644
> +index 0000000000..f366b9567d
> +--- /dev/null
> ++++ b/nscd/nscd-inet_addr.c
> +@@ -0,0 +1,32 @@
> ++/* Legacy IPv4 text-to-address functions.  Version for nscd.
> ++   Copyright (C) 2019 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 <arpa/inet.h>
> ++
> ++/* We do not want to export __inet_aton_exact.  Get the prototype and
> ++   change the visibility to hidden.  */
> ++#include <arpa/inet.h>
> ++__typeof__ (__inet_aton_exact) __inet_aton_exact
> ++  __attribute__ ((visibility ("hidden")));
> ++
> ++/* Do not provide definitions of the public symbols exported from
> ++   libc.  */
> ++#undef weak_alias
> ++#define weak_alias(from, to)
> ++
> ++#include <resolv/inet_addr.c>
> +-- 
> +2.20.1

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openembedded.org/pipermail/openembedded-core/attachments/20191208/907c9da2/attachment-0001.html>


More information about the Openembedded-core mailing list