summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoss Burton <ross.burton@intel.com>2019-12-09 12:42:16 (GMT)
committerRichard Purdie <richard.purdie@linuxfoundation.org>2019-12-16 23:11:10 (GMT)
commit3de2aeb687287a7ec65925314e4146c40810e6db (patch)
tree0bf1045cfbd234ab702148f7dea60a7d470dc92f
parent962cbc60d73c91b4d355a32327295fa2e1397dd9 (diff)
downloadpoky-3de2aeb687287a7ec65925314e4146c40810e6db.tar.gz
glibc: finish incomplete fix for CVE-2016-10739
Somehow the patch for this CVE only included one of the four required patches. (From OE-Core rev: e7ed139e48b683ebe3e6863886e712998aaa239c) Signed-off-by: Ross Burton <ross.burton@intel.com> Signed-off-by: Armin Kuster <akuster808@gmail.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--meta/recipes-core/glibc/glibc/CVE-2016-10739.patch910
1 files changed, 907 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 7eb55d6..7dc8428 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@intel.com>
5From 8e92ca5dd7a7e38a4dddf1ebc4e1e8f0cb27e4aa Mon Sep 17 00:00:00 2001 5From 8e92ca5dd7a7e38a4dddf1ebc4e1e8f0cb27e4aa Mon Sep 17 00:00:00 2001
6From: Florian Weimer <fweimer@redhat.com> 6From: Florian Weimer <fweimer@redhat.com>
7Date: Mon, 21 Jan 2019 08:59:42 +0100 7Date: Mon, 21 Jan 2019 08:59:42 +0100
8Subject: [PATCH] resolv: Reformat inet_addr, inet_aton to GNU style 8Subject: [PATCH 1/4] resolv: Reformat inet_addr, inet_aton to GNU style
9 9
10(cherry picked from commit 5e30b8ef0758763effa115634e0ed7d8938e4bc0) 10(cherry picked from commit 5e30b8ef0758763effa115634e0ed7d8938e4bc0)
11--- 11---
12 ChangeLog | 5 ++ 12 ChangeLog | 5 ++
13 resolv/inet_addr.c | 192 ++++++++++++++++++++++++++++------------------------- 13 resolv/inet_addr.c | 192 ++++++++++++++++++++++++---------------------
14 2 files changed, 106 insertions(+), 91 deletions(-) 14 2 files changed, 106 insertions(+), 91 deletions(-)
15 15
16diff --git a/resolv/inet_addr.c b/resolv/inet_addr.c 16diff --git a/resolv/inet_addr.c b/resolv/inet_addr.c
@@ -229,4 +229,908 @@ index 022f7ea084..32f58b0e13 100644
229 weak_alias (__inet_aton, inet_aton) 229 weak_alias (__inet_aton, inet_aton)
230 libc_hidden_def (__inet_aton) 230 libc_hidden_def (__inet_aton)
231-- 231--
2322.11.0 2322.20.1
233
234
235From 37edf1d3f8ab9adefb61cc466ac52b53114fbd5b Mon Sep 17 00:00:00 2001
236From: Florian Weimer <fweimer@redhat.com>
237Date: Mon, 21 Jan 2019 09:26:41 +0100
238Subject: [PATCH 2/4] resolv: Do not send queries for non-host-names in nss_dns
239 [BZ #24112]
240
241Before this commit, nss_dns would send a query which did not contain a
242host name as the query name (such as invalid\032name.example.com) and
243then reject the answer in getanswer_r and gaih_getanswer_slice, using
244a check based on res_hnok. With this commit, no query is sent, and a
245host-not-found error is returned to NSS without network interaction.
246
247(cherry picked from commit 6ca53a2453598804a2559a548a08424fca96434a)
248---
249 ChangeLog | 9 +++++++++
250 resolv/nss_dns/dns-host.c | 24 ++++++++++++++++++++++--
251 2 files changed, 31 insertions(+), 2 deletions(-)
252
253diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
254index 5dc2829cd1..99c3b61e1c 100644
255--- a/resolv/nss_dns/dns-host.c
256+++ b/resolv/nss_dns/dns-host.c
257@@ -274,11 +274,26 @@ gethostbyname3_context (struct resolv_context *ctx,
258 return status;
259 }
260
261+/* Verify that the name looks like a host name. There is no point in
262+ sending a query which will not produce a usable name in the
263+ response. */
264+static enum nss_status
265+check_name (const char *name, int *h_errnop)
266+{
267+ if (res_hnok (name))
268+ return NSS_STATUS_SUCCESS;
269+ *h_errnop = HOST_NOT_FOUND;
270+ return NSS_STATUS_NOTFOUND;
271+}
272+
273 enum nss_status
274 _nss_dns_gethostbyname2_r (const char *name, int af, struct hostent *result,
275 char *buffer, size_t buflen, int *errnop,
276 int *h_errnop)
277 {
278+ enum nss_status status = check_name (name, h_errnop);
279+ if (status != NSS_STATUS_SUCCESS)
280+ return status;
281 return _nss_dns_gethostbyname3_r (name, af, result, buffer, buflen, errnop,
282 h_errnop, NULL, NULL);
283 }
284@@ -289,6 +304,9 @@ _nss_dns_gethostbyname_r (const char *name, struct hostent *result,
285 char *buffer, size_t buflen, int *errnop,
286 int *h_errnop)
287 {
288+ enum nss_status status = check_name (name, h_errnop);
289+ if (status != NSS_STATUS_SUCCESS)
290+ return status;
291 struct resolv_context *ctx = __resolv_context_get ();
292 if (ctx == NULL)
293 {
294@@ -296,7 +314,7 @@ _nss_dns_gethostbyname_r (const char *name, struct hostent *result,
295 *h_errnop = NETDB_INTERNAL;
296 return NSS_STATUS_UNAVAIL;
297 }
298- enum nss_status status = NSS_STATUS_NOTFOUND;
299+ status = NSS_STATUS_NOTFOUND;
300 if (res_use_inet6 ())
301 status = gethostbyname3_context (ctx, name, AF_INET6, result, buffer,
302 buflen, errnop, h_errnop, NULL, NULL);
303@@ -313,6 +331,9 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
304 char *buffer, size_t buflen, int *errnop,
305 int *herrnop, int32_t *ttlp)
306 {
307+ enum nss_status status = check_name (name, herrnop);
308+ if (status != NSS_STATUS_SUCCESS)
309+ return status;
310 struct resolv_context *ctx = __resolv_context_get ();
311 if (ctx == NULL)
312 {
313@@ -347,7 +368,6 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
314 int ans2p_malloced = 0;
315
316 int olderr = errno;
317- enum nss_status status;
318 int n = __res_context_search (ctx, name, C_IN, T_QUERY_A_AND_AAAA,
319 host_buffer.buf->buf, 2048, &host_buffer.ptr,
320 &ans2p, &nans2p, &resplen2, &ans2p_malloced);
321--
3222.20.1
323
324
325From 2373941bd73cb288c8a42a33e23e7f7bb81151e7 Mon Sep 17 00:00:00 2001
326From: Florian Weimer <fweimer@redhat.com>
327Date: Mon, 21 Jan 2019 21:26:03 +0100
328Subject: [PATCH 3/4] CVE-2016-10739: getaddrinfo: Fully parse IPv4 address
329 strings [BZ #20018]
330
331The IPv4 address parser in the getaddrinfo function is changed so that
332it does not ignore trailing whitespace and all characters after it.
333For backwards compatibility, the getaddrinfo function still recognizes
334legacy name syntax, such as 192.000.002.010 interpreted as 192.0.2.8
335(octal).
336
337This commit does not change the behavior of inet_addr and inet_aton.
338gethostbyname already had additional sanity checks (but is switched
339over to the new __inet_aton_exact function for completeness as well).
340
341To avoid sending the problematic query names over DNS, commit
3426ca53a2453598804a2559a548a08424fca96434a ("resolv: Do not send queries
343for non-host-names in nss_dns [BZ #24112]") is needed.
344
345(cherry picked from commit 108bc4049f8ae82710aec26a92ffdb4b439c83fd)
346---
347 ChangeLog | 33 ++++++++
348 NEWS | 4 +
349 include/arpa/inet.h | 6 +-
350 nscd/gai.c | 1 -
351 nscd/gethstbynm3_r.c | 2 -
352 nss/digits_dots.c | 3 +-
353 resolv/Makefile | 7 ++
354 resolv/Versions | 1 +
355 resolv/inet_addr.c | 62 ++++++++++-----
356 resolv/res_init.c | 17 ++--
357 resolv/tst-aton.c | 35 +++++++--
358 resolv/tst-inet_aton_exact.c | 47 +++++++++++
359 resolv/tst-resolv-nondecimal.c | 139 +++++++++++++++++++++++++++++++++
360 resolv/tst-resolv-trailing.c | 136 ++++++++++++++++++++++++++++++++
361 sysdeps/posix/getaddrinfo.c | 2 +-
362 15 files changed, 455 insertions(+), 40 deletions(-)
363 create mode 100644 resolv/tst-inet_aton_exact.c
364 create mode 100644 resolv/tst-resolv-nondecimal.c
365 create mode 100644 resolv/tst-resolv-trailing.c
366
367diff --git a/include/arpa/inet.h b/include/arpa/inet.h
368index c3f28f2baa..19aec74275 100644
369--- a/include/arpa/inet.h
370+++ b/include/arpa/inet.h
371@@ -1,10 +1,10 @@
372 #include <inet/arpa/inet.h>
373
374 #ifndef _ISOMAC
375-extern int __inet_aton (const char *__cp, struct in_addr *__inp);
376-libc_hidden_proto (__inet_aton)
377+/* Variant of inet_aton which rejects trailing garbage. */
378+extern int __inet_aton_exact (const char *__cp, struct in_addr *__inp);
379+libc_hidden_proto (__inet_aton_exact)
380
381-libc_hidden_proto (inet_aton)
382 libc_hidden_proto (inet_ntop)
383 libc_hidden_proto (inet_pton)
384 extern __typeof (inet_pton) __inet_pton;
385diff --git a/nscd/gai.c b/nscd/gai.c
386index 24bdfee1db..f57f396f57 100644
387--- a/nscd/gai.c
388+++ b/nscd/gai.c
389@@ -19,7 +19,6 @@
390
391 /* This file uses the getaddrinfo code but it compiles it without NSCD
392 support. We just need a few symbol renames. */
393-#define __inet_aton inet_aton
394 #define __ioctl ioctl
395 #define __getsockname getsockname
396 #define __socket socket
397diff --git a/nscd/gethstbynm3_r.c b/nscd/gethstbynm3_r.c
398index 7beb9dce9f..f792c4fcd0 100644
399--- a/nscd/gethstbynm3_r.c
400+++ b/nscd/gethstbynm3_r.c
401@@ -38,8 +38,6 @@
402 #define HAVE_LOOKUP_BUFFER 1
403 #define HAVE_AF 1
404
405-#define __inet_aton inet_aton
406-
407 /* We are nscd, so we don't want to be talking to ourselves. */
408 #undef USE_NSCD
409
410diff --git a/nss/digits_dots.c b/nss/digits_dots.c
411index 39bff38865..5441bce16e 100644
412--- a/nss/digits_dots.c
413+++ b/nss/digits_dots.c
414@@ -29,7 +29,6 @@
415 #include "nsswitch.h"
416
417 #ifdef USE_NSCD
418-# define inet_aton __inet_aton
419 # include <nscd/nscd_proto.h>
420 #endif
421
422@@ -160,7 +159,7 @@ __nss_hostname_digits_dots_context (struct resolv_context *ctx,
423 255.255.255.255? The test below will succeed
424 spuriously... ??? */
425 if (af == AF_INET)
426- ok = __inet_aton (name, (struct in_addr *) host_addr);
427+ ok = __inet_aton_exact (name, (struct in_addr *) host_addr);
428 else
429 {
430 assert (af == AF_INET6);
431diff --git a/resolv/Makefile b/resolv/Makefile
432index ea395ac3eb..d36eedd34a 100644
433--- a/resolv/Makefile
434+++ b/resolv/Makefile
435@@ -34,6 +34,9 @@ routines := herror inet_addr inet_ntop inet_pton nsap_addr res_init \
436 tests = tst-aton tst-leaks tst-inet_ntop
437 xtests = tst-leaks2
438
439+tests-internal += tst-inet_aton_exact
440+
441+
442 generate := mtrace-tst-leaks.out tst-leaks.mtrace tst-leaks2.mtrace
443
444 extra-libs := libresolv libnss_dns
445@@ -54,8 +57,10 @@ tests += \
446 tst-resolv-binary \
447 tst-resolv-edns \
448 tst-resolv-network \
449+ tst-resolv-nondecimal \
450 tst-resolv-res_init-multi \
451 tst-resolv-search \
452+ tst-resolv-trailing \
453
454 # These tests need libdl.
455 ifeq (yes,$(build-shared))
456@@ -190,9 +195,11 @@ $(objpfx)tst-resolv-res_init-multi: $(objpfx)libresolv.so \
457 $(shared-thread-library)
458 $(objpfx)tst-resolv-res_init-thread: $(libdl) $(objpfx)libresolv.so \
459 $(shared-thread-library)
460+$(objpfx)tst-resolv-nondecimal: $(objpfx)libresolv.so $(shared-thread-library)
461 $(objpfx)tst-resolv-qtypes: $(objpfx)libresolv.so $(shared-thread-library)
462 $(objpfx)tst-resolv-rotate: $(objpfx)libresolv.so $(shared-thread-library)
463 $(objpfx)tst-resolv-search: $(objpfx)libresolv.so $(shared-thread-library)
464+$(objpfx)tst-resolv-trailing: $(objpfx)libresolv.so $(shared-thread-library)
465 $(objpfx)tst-resolv-threads: \
466 $(libdl) $(objpfx)libresolv.so $(shared-thread-library)
467 $(objpfx)tst-resolv-canonname: \
468diff --git a/resolv/Versions b/resolv/Versions
469index b05778d965..9a82704af7 100644
470--- a/resolv/Versions
471+++ b/resolv/Versions
472@@ -27,6 +27,7 @@ libc {
473 __h_errno; __resp;
474
475 __res_iclose;
476+ __inet_aton_exact;
477 __inet_pton_length;
478 __resolv_context_get;
479 __resolv_context_get_preinit;
480diff --git a/resolv/inet_addr.c b/resolv/inet_addr.c
481index 32f58b0e13..41b6166a5b 100644
482--- a/resolv/inet_addr.c
483+++ b/resolv/inet_addr.c
484@@ -96,26 +96,14 @@
485 #include <limits.h>
486 #include <errno.h>
487
488-/* ASCII IPv4 Internet address interpretation routine. The value
489- returned is in network order. */
490-in_addr_t
491-__inet_addr (const char *cp)
492-{
493- struct in_addr val;
494-
495- if (__inet_aton (cp, &val))
496- return val.s_addr;
497- return INADDR_NONE;
498-}
499-weak_alias (__inet_addr, inet_addr)
500-
501 /* Check whether "cp" is a valid ASCII representation of an IPv4
502 Internet address and convert it to a binary address. Returns 1 if
503 the address is valid, 0 if not. This replaces inet_addr, the
504 return value from which cannot distinguish between failure and a
505- local broadcast address. */
506-int
507-__inet_aton (const char *cp, struct in_addr *addr)
508+ local broadcast address. Write a pointer to the first
509+ non-converted character to *endp. */
510+static int
511+inet_aton_end (const char *cp, struct in_addr *addr, const char **endp)
512 {
513 static const in_addr_t max[4] = { 0xffffffff, 0xffffff, 0xffff, 0xff };
514 in_addr_t val;
515@@ -180,6 +168,7 @@ __inet_aton (const char *cp, struct in_addr *addr)
516
517 if (addr != NULL)
518 addr->s_addr = res.word | htonl (val);
519+ *endp = cp;
520
521 __set_errno (saved_errno);
522 return 1;
523@@ -188,6 +177,41 @@ __inet_aton (const char *cp, struct in_addr *addr)
524 __set_errno (saved_errno);
525 return 0;
526 }
527-weak_alias (__inet_aton, inet_aton)
528-libc_hidden_def (__inet_aton)
529-libc_hidden_weak (inet_aton)
530+
531+int
532+__inet_aton_exact (const char *cp, struct in_addr *addr)
533+{
534+ struct in_addr val;
535+ const char *endp;
536+ /* Check that inet_aton_end parsed the entire string. */
537+ if (inet_aton_end (cp, &val, &endp) != 0 && *endp == 0)
538+ {
539+ *addr = val;
540+ return 1;
541+ }
542+ else
543+ return 0;
544+}
545+libc_hidden_def (__inet_aton_exact)
546+
547+/* inet_aton ignores trailing garbage. */
548+int
549+__inet_aton_ignore_trailing (const char *cp, struct in_addr *addr)
550+{
551+ const char *endp;
552+ return inet_aton_end (cp, addr, &endp);
553+}
554+weak_alias (__inet_aton_ignore_trailing, inet_aton)
555+
556+/* ASCII IPv4 Internet address interpretation routine. The value
557+ returned is in network order. */
558+in_addr_t
559+__inet_addr (const char *cp)
560+{
561+ struct in_addr val;
562+ const char *endp;
563+ if (inet_aton_end (cp, &val, &endp))
564+ return val.s_addr;
565+ return INADDR_NONE;
566+}
567+weak_alias (__inet_addr, inet_addr)
568diff --git a/resolv/res_init.c b/resolv/res_init.c
569index f5e52cbbb9..94743a252e 100644
570--- a/resolv/res_init.c
571+++ b/resolv/res_init.c
572@@ -399,8 +399,16 @@ res_vinit_1 (FILE *fp, struct resolv_conf_parser *parser)
573 cp = parser->buffer + sizeof ("nameserver") - 1;
574 while (*cp == ' ' || *cp == '\t')
575 cp++;
576+
577+ /* Ignore trailing contents on the name server line. */
578+ {
579+ char *el;
580+ if ((el = strpbrk (cp, " \t\n")) != NULL)
581+ *el = '\0';
582+ }
583+
584 struct sockaddr *sa;
585- if ((*cp != '\0') && (*cp != '\n') && __inet_aton (cp, &a))
586+ if ((*cp != '\0') && (*cp != '\n') && __inet_aton_exact (cp, &a))
587 {
588 sa = allocate_address_v4 (a, NAMESERVER_PORT);
589 if (sa == NULL)
590@@ -410,9 +418,6 @@ res_vinit_1 (FILE *fp, struct resolv_conf_parser *parser)
591 {
592 struct in6_addr a6;
593 char *el;
594-
595- if ((el = strpbrk (cp, " \t\n")) != NULL)
596- *el = '\0';
597 if ((el = strchr (cp, SCOPE_DELIMITER)) != NULL)
598 *el = '\0';
599 if ((*cp != '\0') && (__inet_pton (AF_INET6, cp, &a6) > 0))
600@@ -472,7 +477,7 @@ res_vinit_1 (FILE *fp, struct resolv_conf_parser *parser)
601 char separator = *cp;
602 *cp = 0;
603 struct resolv_sortlist_entry e;
604- if (__inet_aton (net, &a))
605+ if (__inet_aton_exact (net, &a))
606 {
607 e.addr = a;
608 if (is_sort_mask (separator))
609@@ -484,7 +489,7 @@ res_vinit_1 (FILE *fp, struct resolv_conf_parser *parser)
610 cp++;
611 separator = *cp;
612 *cp = 0;
613- if (__inet_aton (net, &a))
614+ if (__inet_aton_exact (net, &a))
615 e.mask = a.s_addr;
616 else
617 e.mask = net_mask (e.addr);
618diff --git a/resolv/tst-aton.c b/resolv/tst-aton.c
619index 08110a007a..eb734d7758 100644
620--- a/resolv/tst-aton.c
621+++ b/resolv/tst-aton.c
622@@ -1,11 +1,29 @@
623+/* Test legacy IPv4 text-to-address function inet_aton.
624+ Copyright (C) 1998-2019 Free Software Foundation, Inc.
625+ This file is part of the GNU C Library.
626+
627+ The GNU C Library is free software; you can redistribute it and/or
628+ modify it under the terms of the GNU Lesser General Public
629+ License as published by the Free Software Foundation; either
630+ version 2.1 of the License, or (at your option) any later version.
631+
632+ The GNU C Library is distributed in the hope that it will be useful,
633+ but WITHOUT ANY WARRANTY; without even the implied warranty of
634+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
635+ Lesser General Public License for more details.
636+
637+ You should have received a copy of the GNU Lesser General Public
638+ License along with the GNU C Library; if not, see
639+ <http://www.gnu.org/licenses/>. */
640+
641+#include <array_length.h>
642 #include <stdio.h>
643 #include <stdint.h>
644 #include <sys/socket.h>
645 #include <netinet/in.h>
646 #include <arpa/inet.h>
647
648-
649-static struct tests
650+static const struct tests
651 {
652 const char *input;
653 int valid;
654@@ -16,6 +34,7 @@ static struct tests
655 { "-1", 0, 0 },
656 { "256", 1, 0x00000100 },
657 { "256.", 0, 0 },
658+ { "255a", 0, 0 },
659 { "256a", 0, 0 },
660 { "0x100", 1, 0x00000100 },
661 { "0200.0x123456", 1, 0x80123456 },
662@@ -40,7 +59,12 @@ static struct tests
663 { "1.2.256.4", 0, 0 },
664 { "1.2.3.0x100", 0, 0 },
665 { "323543357756889", 0, 0 },
666- { "10.1.2.3.4", 0, 0},
667+ { "10.1.2.3.4", 0, 0 },
668+ { "192.0.2.1", 1, 0xc0000201 },
669+ { "192.0.2.2\nX", 1, 0xc0000202 },
670+ { "192.0.2.3 Y", 1, 0xc0000203 },
671+ { "192.0.2.3Z", 0, 0 },
672+ { "192.000.002.010", 1, 0xc0000208 },
673 };
674
675
676@@ -50,7 +74,7 @@ do_test (void)
677 int result = 0;
678 size_t cnt;
679
680- for (cnt = 0; cnt < sizeof (tests) / sizeof (tests[0]); ++cnt)
681+ for (cnt = 0; cnt < array_length (tests); ++cnt)
682 {
683 struct in_addr addr;
684
685@@ -73,5 +97,4 @@ do_test (void)
686 return result;
687 }
688
689-#define TEST_FUNCTION do_test ()
690-#include "../test-skeleton.c"
691+#include <support/test-driver.c>
692diff --git a/resolv/tst-inet_aton_exact.c b/resolv/tst-inet_aton_exact.c
693new file mode 100644
694index 0000000000..0fdfa3d6aa
695--- /dev/null
696+++ b/resolv/tst-inet_aton_exact.c
697@@ -0,0 +1,47 @@
698+/* Test internal legacy IPv4 text-to-address function __inet_aton_exact.
699+ Copyright (C) 2019 Free Software Foundation, Inc.
700+ This file is part of the GNU C Library.
701+
702+ The GNU C Library is free software; you can redistribute it and/or
703+ modify it under the terms of the GNU Lesser General Public
704+ License as published by the Free Software Foundation; either
705+ version 2.1 of the License, or (at your option) any later version.
706+
707+ The GNU C Library is distributed in the hope that it will be useful,
708+ but WITHOUT ANY WARRANTY; without even the implied warranty of
709+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
710+ Lesser General Public License for more details.
711+
712+ You should have received a copy of the GNU Lesser General Public
713+ License along with the GNU C Library; if not, see
714+ <http://www.gnu.org/licenses/>. */
715+
716+#include <arpa/inet.h>
717+#include <support/check.h>
718+
719+static int
720+do_test (void)
721+{
722+ struct in_addr addr = { };
723+
724+ TEST_COMPARE (__inet_aton_exact ("192.0.2.1", &addr), 1);
725+ TEST_COMPARE (ntohl (addr.s_addr), 0xC0000201);
726+
727+ TEST_COMPARE (__inet_aton_exact ("192.000.002.010", &addr), 1);
728+ TEST_COMPARE (ntohl (addr.s_addr), 0xC0000208);
729+ TEST_COMPARE (__inet_aton_exact ("0xC0000234", &addr), 1);
730+ TEST_COMPARE (ntohl (addr.s_addr), 0xC0000234);
731+
732+ /* Trailing content is not accepted. */
733+ TEST_COMPARE (__inet_aton_exact ("192.0.2.2X", &addr), 0);
734+ TEST_COMPARE (__inet_aton_exact ("192.0.2.3 Y", &addr), 0);
735+ TEST_COMPARE (__inet_aton_exact ("192.0.2.4\nZ", &addr), 0);
736+ TEST_COMPARE (__inet_aton_exact ("192.0.2.5\tT", &addr), 0);
737+ TEST_COMPARE (__inet_aton_exact ("192.0.2.6 Y", &addr), 0);
738+ TEST_COMPARE (__inet_aton_exact ("192.0.2.7\n", &addr), 0);
739+ TEST_COMPARE (__inet_aton_exact ("192.0.2.8\t", &addr), 0);
740+
741+ return 0;
742+}
743+
744+#include <support/test-driver.c>
745diff --git a/resolv/tst-resolv-nondecimal.c b/resolv/tst-resolv-nondecimal.c
746new file mode 100644
747index 0000000000..a0df6f332a
748--- /dev/null
749+++ b/resolv/tst-resolv-nondecimal.c
750@@ -0,0 +1,139 @@
751+/* Test name resolution behavior for octal, hexadecimal IPv4 addresses.
752+ Copyright (C) 2019 Free Software Foundation, Inc.
753+ This file is part of the GNU C Library.
754+
755+ The GNU C Library is free software; you can redistribute it and/or
756+ modify it under the terms of the GNU Lesser General Public
757+ License as published by the Free Software Foundation; either
758+ version 2.1 of the License, or (at your option) any later version.
759+
760+ The GNU C Library is distributed in the hope that it will be useful,
761+ but WITHOUT ANY WARRANTY; without even the implied warranty of
762+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
763+ Lesser General Public License for more details.
764+
765+ You should have received a copy of the GNU Lesser General Public
766+ License along with the GNU C Library; if not, see
767+ <http://www.gnu.org/licenses/>. */
768+
769+#include <netdb.h>
770+#include <stdlib.h>
771+#include <support/check.h>
772+#include <support/check_nss.h>
773+#include <support/resolv_test.h>
774+#include <support/support.h>
775+
776+static void
777+response (const struct resolv_response_context *ctx,
778+ struct resolv_response_builder *b,
779+ const char *qname, uint16_t qclass, uint16_t qtype)
780+{
781+ /* The tests are not supposed send any DNS queries. */
782+ FAIL_EXIT1 ("unexpected DNS query for %s/%d/%d", qname, qclass, qtype);
783+}
784+
785+static void
786+run_query_addrinfo (const char *query, const char *address)
787+{
788+ char *quoted_query = support_quote_string (query);
789+
790+ struct addrinfo *ai;
791+ struct addrinfo hints =
792+ {
793+ .ai_socktype = SOCK_STREAM,
794+ .ai_protocol = IPPROTO_TCP,
795+ };
796+
797+ char *context = xasprintf ("getaddrinfo \"%s\" AF_INET", quoted_query);
798+ char *expected = xasprintf ("address: STREAM/TCP %s 80\n", address);
799+ hints.ai_family = AF_INET;
800+ int ret = getaddrinfo (query, "80", &hints, &ai);
801+ check_addrinfo (context, ai, ret, expected);
802+ if (ret == 0)
803+ freeaddrinfo (ai);
804+ free (context);
805+
806+ context = xasprintf ("getaddrinfo \"%s\" AF_UNSPEC", quoted_query);
807+ hints.ai_family = AF_UNSPEC;
808+ ret = getaddrinfo (query, "80", &hints, &ai);
809+ check_addrinfo (context, ai, ret, expected);
810+ if (ret == 0)
811+ freeaddrinfo (ai);
812+ free (expected);
813+ free (context);
814+
815+ context = xasprintf ("getaddrinfo \"%s\" AF_INET6", quoted_query);
816+ expected = xasprintf ("flags: AI_V4MAPPED\n"
817+ "address: STREAM/TCP ::ffff:%s 80\n",
818+ address);
819+ hints.ai_family = AF_INET6;
820+ hints.ai_flags = AI_V4MAPPED;
821+ ret = getaddrinfo (query, "80", &hints, &ai);
822+ check_addrinfo (context, ai, ret, expected);
823+ if (ret == 0)
824+ freeaddrinfo (ai);
825+ free (expected);
826+ free (context);
827+
828+ free (quoted_query);
829+}
830+
831+static void
832+run_query (const char *query, const char *address)
833+{
834+ char *quoted_query = support_quote_string (query);
835+ char *context = xasprintf ("gethostbyname (\"%s\")", quoted_query);
836+ char *expected = xasprintf ("name: %s\n"
837+ "address: %s\n", query, address);
838+ check_hostent (context, gethostbyname (query), expected);
839+ free (context);
840+
841+ context = xasprintf ("gethostbyname_r \"%s\"", quoted_query);
842+ struct hostent storage;
843+ char buf[4096];
844+ struct hostent *e = NULL;
845+ TEST_COMPARE (gethostbyname_r (query, &storage, buf, sizeof (buf),
846+ &e, &h_errno), 0);
847+ check_hostent (context, e, expected);
848+ free (context);
849+
850+ context = xasprintf ("gethostbyname2 (\"%s\", AF_INET)", quoted_query);
851+ check_hostent (context, gethostbyname2 (query, AF_INET), expected);
852+ free (context);
853+
854+ context = xasprintf ("gethostbyname2_r \"%s\" AF_INET", quoted_query);
855+ e = NULL;
856+ TEST_COMPARE (gethostbyname2_r (query, AF_INET, &storage, buf, sizeof (buf),
857+ &e, &h_errno), 0);
858+ check_hostent (context, e, expected);
859+ free (context);
860+ free (expected);
861+
862+ free (quoted_query);
863+
864+ /* The gethostbyname tests are always valid for getaddrinfo, but not
865+ vice versa. */
866+ run_query_addrinfo (query, address);
867+}
868+
869+static int
870+do_test (void)
871+{
872+ struct resolv_test *aux = resolv_test_start
873+ ((struct resolv_redirect_config)
874+ {
875+ .response_callback = response,
876+ });
877+
878+ run_query ("192.000.002.010", "192.0.2.8");
879+
880+ /* Hexadecimal numbers are not accepted by gethostbyname. */
881+ run_query_addrinfo ("0xc0000210", "192.0.2.16");
882+ run_query_addrinfo ("192.0x234", "192.0.2.52");
883+
884+ resolv_test_end (aux);
885+
886+ return 0;
887+}
888+
889+#include <support/test-driver.c>
890diff --git a/resolv/tst-resolv-trailing.c b/resolv/tst-resolv-trailing.c
891new file mode 100644
892index 0000000000..7504bdae57
893--- /dev/null
894+++ b/resolv/tst-resolv-trailing.c
895@@ -0,0 +1,136 @@
896+/* Test name resolution behavior with trailing characters.
897+ Copyright (C) 2019 Free Software Foundation, Inc.
898+ This file is part of the GNU C Library.
899+
900+ The GNU C Library is free software; you can redistribute it and/or
901+ modify it under the terms of the GNU Lesser General Public
902+ License as published by the Free Software Foundation; either
903+ version 2.1 of the License, or (at your option) any later version.
904+
905+ The GNU C Library is distributed in the hope that it will be useful,
906+ but WITHOUT ANY WARRANTY; without even the implied warranty of
907+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
908+ Lesser General Public License for more details.
909+
910+ You should have received a copy of the GNU Lesser General Public
911+ License along with the GNU C Library; if not, see
912+ <http://www.gnu.org/licenses/>. */
913+
914+#include <array_length.h>
915+#include <netdb.h>
916+#include <support/check.h>
917+#include <support/check_nss.h>
918+#include <support/resolv_test.h>
919+#include <support/support.h>
920+
921+static void
922+response (const struct resolv_response_context *ctx,
923+ struct resolv_response_builder *b,
924+ const char *qname, uint16_t qclass, uint16_t qtype)
925+{
926+ /* The tests are not supposed send any DNS queries. */
927+ FAIL_EXIT1 ("unexpected DNS query for %s/%d/%d", qname, qclass, qtype);
928+}
929+
930+static int
931+do_test (void)
932+{
933+ struct resolv_test *aux = resolv_test_start
934+ ((struct resolv_redirect_config)
935+ {
936+ .response_callback = response,
937+ });
938+
939+ static const char *const queries[] =
940+ {
941+ "192.0.2.1 ",
942+ "192.0.2.2\t",
943+ "192.0.2.3\n",
944+ "192.0.2.4 X",
945+ "192.0.2.5\tY",
946+ "192.0.2.6\nZ",
947+ "192.0.2. ",
948+ "192.0.2.\t",
949+ "192.0.2.\n",
950+ "192.0.2. X",
951+ "192.0.2.\tY",
952+ "192.0.2.\nZ",
953+ "2001:db8::1 ",
954+ "2001:db8::2\t",
955+ "2001:db8::3\n",
956+ "2001:db8::4 X",
957+ "2001:db8::5\tY",
958+ "2001:db8::6\nZ",
959+ };
960+ for (size_t query_idx = 0; query_idx < array_length (queries); ++query_idx)
961+ {
962+ const char *query = queries[query_idx];
963+ struct hostent storage;
964+ char buf[4096];
965+ struct hostent *e;
966+
967+ h_errno = 0;
968+ TEST_VERIFY (gethostbyname (query) == NULL);
969+ TEST_COMPARE (h_errno, HOST_NOT_FOUND);
970+
971+ h_errno = 0;
972+ e = NULL;
973+ TEST_COMPARE (gethostbyname_r (query, &storage, buf, sizeof (buf),
974+ &e, &h_errno), 0);
975+ TEST_VERIFY (e == NULL);
976+ TEST_COMPARE (h_errno, HOST_NOT_FOUND);
977+
978+ h_errno = 0;
979+ TEST_VERIFY (gethostbyname2 (query, AF_INET) == NULL);
980+ TEST_COMPARE (h_errno, HOST_NOT_FOUND);
981+
982+ h_errno = 0;
983+ e = NULL;
984+ TEST_COMPARE (gethostbyname2_r (query, AF_INET,
985+ &storage, buf, sizeof (buf),
986+ &e, &h_errno), 0);
987+ TEST_VERIFY (e == NULL);
988+ TEST_COMPARE (h_errno, HOST_NOT_FOUND);
989+
990+ h_errno = 0;
991+ TEST_VERIFY (gethostbyname2 (query, AF_INET6) == NULL);
992+ TEST_COMPARE (h_errno, HOST_NOT_FOUND);
993+
994+ h_errno = 0;
995+ e = NULL;
996+ TEST_COMPARE (gethostbyname2_r (query, AF_INET6,
997+ &storage, buf, sizeof (buf),
998+ &e, &h_errno), 0);
999+ TEST_VERIFY (e == NULL);
1000+ TEST_COMPARE (h_errno, HOST_NOT_FOUND);
1001+
1002+ static const int gai_flags[] =
1003+ {
1004+ 0,
1005+ AI_ADDRCONFIG,
1006+ AI_NUMERICHOST,
1007+ AI_IDN,
1008+ AI_IDN | AI_NUMERICHOST,
1009+ AI_V4MAPPED,
1010+ AI_V4MAPPED | AI_NUMERICHOST,
1011+ };
1012+ for (size_t gai_flags_idx; gai_flags_idx < array_length (gai_flags);
1013+ ++gai_flags_idx)
1014+ {
1015+ struct addrinfo hints = { .ai_flags = gai_flags[gai_flags_idx], };
1016+ struct addrinfo *ai;
1017+ hints.ai_family = AF_INET;
1018+ TEST_COMPARE (getaddrinfo (query, "80", &hints, &ai), EAI_NONAME);
1019+ hints.ai_family = AF_INET6;
1020+ TEST_COMPARE (getaddrinfo (query, "80", &hints, &ai), EAI_NONAME);
1021+ hints.ai_family = AF_UNSPEC;
1022+ TEST_COMPARE (getaddrinfo (query, "80", &hints, &ai), EAI_NONAME);
1023+ }
1024+ };
1025+
1026+ resolv_test_end (aux);
1027+
1028+ return 0;
1029+}
1030+
1031+#include <support/test-driver.c>
1032diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
1033index 553833d1f2..c91b281e31 100644
1034--- a/sysdeps/posix/getaddrinfo.c
1035+++ b/sysdeps/posix/getaddrinfo.c
1036@@ -488,7 +488,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
1037 malloc_name = true;
1038 }
1039
1040- if (__inet_aton (name, (struct in_addr *) at->addr) != 0)
1041+ if (__inet_aton_exact (name, (struct in_addr *) at->addr) != 0)
1042 {
1043 if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
1044 at->family = AF_INET;
1045--
10462.20.1
1047
1048
1049From c533244b8e00ae701583ec50aeb43377d292452d Mon Sep 17 00:00:00 2001
1050From: Florian Weimer <fweimer@redhat.com>
1051Date: Mon, 4 Feb 2019 20:07:18 +0100
1052Subject: [PATCH 4/4] nscd: Do not use __inet_aton_exact@GLIBC_PRIVATE [BZ
1053 #20018]
1054
1055This commit avoids referencing the __inet_aton_exact@GLIBC_PRIVATE
1056symbol from nscd. In master, the separately-compiled getaddrinfo
1057implementation in nscd needs it, however such an internal ABI change
1058is not desirable on a release branch if it can be avoided.
1059---
1060 ChangeLog | 10 ++++++++++
1061 nscd/Makefile | 2 +-
1062 nscd/gai.c | 6 ++++++
1063 nscd/nscd-inet_addr.c | 32 ++++++++++++++++++++++++++++++++
1064 4 files changed, 49 insertions(+), 1 deletion(-)
1065 create mode 100644 nscd/nscd-inet_addr.c
1066
1067diff --git a/nscd/Makefile b/nscd/Makefile
1068index b713a84c49..eb23c01a39 100644
1069--- a/nscd/Makefile
1070+++ b/nscd/Makefile
1071@@ -36,7 +36,7 @@ nscd-modules := nscd connections pwdcache getpwnam_r getpwuid_r grpcache \
1072 getsrvbynm_r getsrvbypt_r servicescache \
1073 dbg_log nscd_conf nscd_stat cache mem nscd_setup_thread \
1074 xmalloc xstrdup aicache initgrcache gai res_hconf \
1075- netgroupcache
1076+ netgroupcache nscd-inet_addr
1077
1078 ifeq ($(build-nscd)$(have-thread-library),yesyes)
1079
1080diff --git a/nscd/gai.c b/nscd/gai.c
1081index f57f396f57..68a4abd30e 100644
1082--- a/nscd/gai.c
1083+++ b/nscd/gai.c
1084@@ -33,6 +33,12 @@
1085 #define __getifaddrs getifaddrs
1086 #define __freeifaddrs freeifaddrs
1087
1088+/* We do not want to export __inet_aton_exact. Get the prototype and
1089+ change its visibility to hidden. */
1090+#include <arpa/inet.h>
1091+__typeof__ (__inet_aton_exact) __inet_aton_exact
1092+ __attribute__ ((visibility ("hidden")));
1093+
1094 /* We are nscd, so we don't want to be talking to ourselves. */
1095 #undef USE_NSCD
1096
1097diff --git a/nscd/nscd-inet_addr.c b/nscd/nscd-inet_addr.c
1098new file mode 100644
1099index 0000000000..f366b9567d
1100--- /dev/null
1101+++ b/nscd/nscd-inet_addr.c
1102@@ -0,0 +1,32 @@
1103+/* Legacy IPv4 text-to-address functions. Version for nscd.
1104+ Copyright (C) 2019 Free Software Foundation, Inc.
1105+ This file is part of the GNU C Library.
1106+
1107+ The GNU C Library is free software; you can redistribute it and/or
1108+ modify it under the terms of the GNU Lesser General Public
1109+ License as published by the Free Software Foundation; either
1110+ version 2.1 of the License, or (at your option) any later version.
1111+
1112+ The GNU C Library is distributed in the hope that it will be useful,
1113+ but WITHOUT ANY WARRANTY; without even the implied warranty of
1114+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1115+ Lesser General Public License for more details.
1116+
1117+ You should have received a copy of the GNU Lesser General Public
1118+ License along with the GNU C Library; if not, see
1119+ <http://www.gnu.org/licenses/>. */
1120+
1121+#include <arpa/inet.h>
1122+
1123+/* We do not want to export __inet_aton_exact. Get the prototype and
1124+ change the visibility to hidden. */
1125+#include <arpa/inet.h>
1126+__typeof__ (__inet_aton_exact) __inet_aton_exact
1127+ __attribute__ ((visibility ("hidden")));
1128+
1129+/* Do not provide definitions of the public symbols exported from
1130+ libc. */
1131+#undef weak_alias
1132+#define weak_alias(from, to)
1133+
1134+#include <resolv/inet_addr.c>
1135--
11362.20.1