This is the mail archive of the glibc-cvs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

GNU C Library master sources branch master updated. glibc-2.25-538-g60149b2


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, master has been updated
       via  60149b28590be28051f99d0a343d7fbe002f2a8c (commit)
      from  965d5c391c86eb3a812ce308411c32754f12a9d2 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=60149b28590be28051f99d0a343d7fbe002f2a8c

commit 60149b28590be28051f99d0a343d7fbe002f2a8c
Author: Florian Weimer <fweimer@redhat.com>
Date:   Wed Jun 21 13:09:08 2017 +0200

    __inet_pton_length: Implement new internal helper function

diff --git a/ChangeLog b/ChangeLog
index 58cf98c..a3a8284 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,23 @@
 2017-06-21  Florian Weimer  <fweimer@redhat.com>
 
+	Add the __inet_pton_length helper function.
+	* resolv/resolv-internal.h (__inet_pton_length): Declare.
+	* resolv/inet_pton (__inet_pton_length): Rename from __inet_pton.
+	Add length argument.
+	(__inet_pton): New function.
+	(inet_pton4): Add length argument.
+	(hex_digit_value): New function.
+	(inet_pton6): Add length argument.  Call hex_digit_value.  Use
+	memmove and memset to fill :: gap.
+	* resolv/Makefile (tests, tsts-static, tests-internal): Add
+	tst-inet_pton.
+	* resolv/tst-inet_pton.c: New file.
+	* support/Makefile (libsupport-routines): Add xmprotect.
+	* support/xunistd.h (xmprotect): Declare.
+	* support/xmprotect.c: New file.
+
+2017-06-21  Florian Weimer  <fweimer@redhat.com>
+
 	Add IPv6 getaddrinfo coverage to tst-inet6_scopeid_pton.c.
 	* inet/tst-inet6_scopeid_pton.c: Switch to <support/test-driver.c>.
 	(call_gai, check_ai): New functions.
diff --git a/resolv/Makefile b/resolv/Makefile
index a9b355f..8294d94 100644
--- a/resolv/Makefile
+++ b/resolv/Makefile
@@ -64,6 +64,9 @@ tests-internal += \
 
 endif
 
+# This test accesses __inet_ntop_range, an internal libc function.
+tests-internal += tst-inet_pton
+
 # This test sends millions of packets and is rather slow.
 xtests += tst-resolv-qtypes
 endif
diff --git a/resolv/Versions b/resolv/Versions
index e561bce..f528ed5 100644
--- a/resolv/Versions
+++ b/resolv/Versions
@@ -27,6 +27,7 @@ libc {
     __h_errno; __resp;
 
     __res_maybe_init; __res_iclose;
+    __inet_pton_length;
   }
 }
 
diff --git a/resolv/inet_pton.c b/resolv/inet_pton.c
index 68f0fa5..b95da47 100644
--- a/resolv/inet_pton.c
+++ b/resolv/inet_pton.c
@@ -1,3 +1,20 @@
+/* Copyright (C) 1996-2017 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/>.  */
+
 /*
  * Copyright (c) 1996,1999 by Internet Software Consortium.
  *
@@ -15,58 +32,53 @@
  * SOFTWARE.
  */
 
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
 #include <arpa/inet.h>
 #include <arpa/nameser.h>
 #include <ctype.h>
-#include <string.h>
 #include <errno.h>
+#include <netinet/in.h>
+#include <resolv/resolv-internal.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/types.h>
 
-static int inet_pton4 (const char *src, unsigned char *dst);
-static int inet_pton6 (const char *src, unsigned char *dst);
+static int inet_pton4 (const char *src, const char *src_end, u_char *dst);
+static int inet_pton6 (const char *src, const char *src_end, u_char *dst);
 
-/* Convert from presentation format (which usually means ASCII printable)
- * to network format (which is usually some kind of binary format).
- *
- * return:
- *      1 if the address was valid for the specified address family
- *      0 if the address wasn't valid (`dst' is untouched in this case)
- *      -1 if some other error occurred (`dst' is untouched in this case, too)
- * author:
- *      Paul Vixie, 1996.
- */
 int
-__inet_pton (int af, const char *src, void *dst)
+__inet_pton_length (int af, const char *src, size_t srclen, void *dst)
 {
   switch (af)
     {
     case AF_INET:
-      return inet_pton4 (src, dst);
+      return inet_pton4 (src, src + srclen, dst);
     case AF_INET6:
-      return inet_pton6 (src, dst);
+      return inet_pton6 (src, src + srclen, dst);
     default:
       __set_errno (EAFNOSUPPORT);
       return -1;
     }
 }
+libc_hidden_def (__inet_pton_length)
+
+/* Like __inet_pton_length, but use strlen (SRC) as the length of
+   SRC.  */
+int
+__inet_pton (int af, const char *src, void *dst)
+{
+  return __inet_pton_length (af, src, strlen (src), dst);
+}
 libc_hidden_def (__inet_pton)
 weak_alias (__inet_pton, inet_pton)
 libc_hidden_weak (inet_pton)
 
-/* Like inet_atonbut without all the hexadecimal, octal and shorthand.
- *
- * return:
- *      1 if `src' is a valid dotted quad, else 0.
- * notice:
- *      does not touch `dst' unless it's returning 1.
- * author:
- *      Paul Vixie, 1996.
- */
+/* Like inet_aton but without all the hexadecimal, octal and shorthand
+   (and trailing garbage is not ignored).  Return 1 if SRC is a valid
+   dotted quad, else 0.  This function does not touch DST unless it's
+   returning 1.
+   Author: Paul Vixie, 1996.  */
 static int
-inet_pton4 (const char *src, unsigned char *dst)
+inet_pton4 (const char *src, const char *end, unsigned char *dst)
 {
   int saw_digit, octets, ch;
   unsigned char tmp[NS_INADDRSZ], *tp;
@@ -74,8 +86,9 @@ inet_pton4 (const char *src, unsigned char *dst)
   saw_digit = 0;
   octets = 0;
   *(tp = tmp) = 0;
-  while ((ch = *src++) != '\0')
+  while (src < end)
     {
+      ch = *src++;
       if (ch >= '0' && ch <= '9')
         {
           unsigned int new = *tp * 10 + (ch - '0');
@@ -108,22 +121,27 @@ inet_pton4 (const char *src, unsigned char *dst)
   return 1;
 }
 
-/* Cconvert presentation level address to network order binary form.
- *
- * return:
- *      1 if `src' is a valid [RFC1884 2.2] address, else 0.
- * notice:
- *      (1) does not touch `dst' unless it's returning 1.
- *      (2) :: in a full address is silently ignored.
- * credit:
- *      inspired by Mark Andrews.
- * author:
- *      Paul Vixie, 1996.
- */
+/* Return the value of CH as a hexademical digit, or -1 if it is a
+   different type of character.  */
+static int
+hex_digit_value (char ch)
+{
+  if ('0' <= ch && ch <= '9')
+    return ch - '0';
+  if ('a' <= ch && ch <= 'f')
+    return ch - 'a' + 10;
+  if ('A' <= ch && ch <= 'F')
+    return ch - 'A' + 10;
+  return -1;
+}
+
+/* Convert presentation-level IPv6 address to network order binary
+   form.  Return 1 if SRC is a valid [RFC1884 2.2] address, else 0.
+   This function does not touch DST unless it's returning 1.
+   Author: Paul Vixie, 1996.  Inspired by Mark Andrews.  */
 static int
-inet_pton6 (const char *src, unsigned char *dst)
+inet_pton6 (const char *src, const char *src_endp, unsigned char *dst)
 {
-  static const char xdigits[] = "0123456789abcdef";
   unsigned char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
   const char *curtok;
   int ch, saw_xdigit;
@@ -132,22 +150,28 @@ inet_pton6 (const char *src, unsigned char *dst)
   tp = memset (tmp, '\0', NS_IN6ADDRSZ);
   endp = tp + NS_IN6ADDRSZ;
   colonp = NULL;
+
   /* Leading :: requires some special handling.  */
+  if (src == src_endp)
+    return 0;
   if (*src == ':')
-    if (*++src != ':')
-      return 0;
+    {
+      ++src;
+      if (src == src_endp || *src != ':')
+        return 0;
+    }
+
   curtok = src;
   saw_xdigit = 0;
   val = 0;
-  while ((ch = tolower (*src++)) != '\0')
+  while (src < src_endp)
     {
-      const char *pch;
-
-      pch = strchr (xdigits, ch);
-      if (pch != NULL)
+      ch = *src++;
+      int digit = hex_digit_value (ch);
+      if (digit >= 0)
 	{
 	  val <<= 4;
-	  val |= (pch - xdigits);
+	  val |= digit;
 	  if (val > 0xffff)
 	    return 0;
 	  saw_xdigit = 1;
@@ -163,10 +187,8 @@ inet_pton6 (const char *src, unsigned char *dst)
 	      colonp = tp;
 	      continue;
 	    }
-	  else if (*src == '\0')
-	    {
-	      return 0;
-	    }
+	  else if (src == src_endp)
+            return 0;
 	  if (tp + NS_INT16SZ > endp)
 	    return 0;
 	  *tp++ = (unsigned char) (val >> 8) & 0xff;
@@ -175,8 +197,8 @@ inet_pton6 (const char *src, unsigned char *dst)
 	  val = 0;
 	  continue;
 	}
-      if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
-	  inet_pton4 (curtok, tp) > 0)
+      if (ch == '.' && ((tp + NS_INADDRSZ) <= endp)
+          && inet_pton4 (curtok, src_endp, tp) > 0)
 	{
 	  tp += NS_INADDRSZ;
 	  saw_xdigit = 0;
@@ -193,20 +215,13 @@ inet_pton6 (const char *src, unsigned char *dst)
     }
   if (colonp != NULL)
     {
-      /*
-       * Since some memmove's erroneously fail to handle
-       * overlapping regions, we'll do the shift by hand.
-       */
-      const int n = tp - colonp;
-      int i;
-
+      /* Replace :: with zeros.  */
       if (tp == endp)
-	return 0;
-      for (i = 1; i <= n; i++)
-	{
-	  endp[- i] = colonp[n - i];
-	  colonp[n - i] = 0;
-	}
+        /* :: would expand to a zero-width field.  */
+        return 0;
+      size_t n = tp - colonp;
+      memmove (endp - n, colonp, n);
+      memset (colonp, 0, endp - n - colonp);
       tp = endp;
     }
   if (tp != endp)
diff --git a/resolv/resolv-internal.h b/resolv/resolv-internal.h
index 0d69ce1..9afaa07 100644
--- a/resolv/resolv-internal.h
+++ b/resolv/resolv-internal.h
@@ -56,4 +56,13 @@ enum
 int __res_nopt (res_state, int n0, unsigned char *buf, int buflen,
                 int anslen) attribute_hidden;
 
+/* Convert from presentation format (which usually means ASCII
+   printable) to network format (which is usually some kind of binary
+   format).  The input is in the range [SRC, SRC + SRCLEN).  The
+   output is written to DST (which has to be 4 or 16 bytes long,
+   depending on AF).  Return 0 for invalid input, 1 for success, -1
+   for an invalid address family.  */
+int __inet_pton_length (int af, const char *src, size_t srclen, void *);
+libc_hidden_proto (__inet_pton_length)
+
 #endif  /* _RESOLV_INTERNAL_H */
diff --git a/resolv/tst-inet_pton.c b/resolv/tst-inet_pton.c
new file mode 100644
index 0000000..7fffb24
--- /dev/null
+++ b/resolv/tst-inet_pton.c
@@ -0,0 +1,549 @@
+/* Test inet_pton functions.
+   Copyright (C) 2017 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 <resolv/resolv-internal.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#include <support/check.h>
+#include <support/xunistd.h>
+#include <sys/mman.h>
+#include <sys/param.h>
+#include <unistd.h>
+
+/* Memory region created by next_to_fault_allocate.  */
+struct next_to_fault
+{
+  /* The user data.  */
+  char *buffer;
+  size_t length;
+
+  /* The entire allocated region.  */
+  void *region_start;
+  size_t region_size;
+};
+
+/* Allocate a buffer of SIZE bytes just before a page which is mapped
+   with PROT_NONE (so that overrunning the buffer will cause a
+   fault).  */
+static struct next_to_fault
+next_to_fault_allocate (size_t size)
+{
+  long page_size = sysconf (_SC_PAGE_SIZE);
+  TEST_VERIFY_EXIT (page_size > 0);
+  struct next_to_fault result;
+  result.region_size = roundup (size, page_size) + page_size;
+  TEST_VERIFY_EXIT (size + page_size > size);
+  TEST_VERIFY_EXIT (result.region_size > size);
+  result.region_start
+    = xmmap (NULL, result.region_size, PROT_READ | PROT_WRITE,
+             MAP_PRIVATE | MAP_ANONYMOUS, -1);
+  /* Unmap the page after the allocation.  */
+  xmprotect (result.region_start + (result.region_size - page_size),
+             page_size, PROT_NONE);
+  /* Align the allocation within the region so that it ends just
+     before the PROT_NONE page.  */
+  result.buffer = result.region_start + result.region_size - page_size - size;
+  result.length = size;
+  return result;
+}
+
+/* Deallocate the memory region allocated by
+   next_to_fault_allocate.  */
+static void
+next_to_fault_free (struct next_to_fault *ntf)
+{
+  xmunmap (ntf->region_start, ntf->region_size);
+  *ntf = (struct next_to_fault) { NULL, };
+}
+
+struct test_case
+{
+  /* The input data.  */
+  const char *input;
+
+  /* True if AF_INET parses successfully.  */
+  bool ipv4_ok;
+
+  /* True if AF_INET6 parses successfully.  */
+  bool ipv6_ok;
+
+  /* Expected result for AF_INET.  */
+  unsigned char ipv4_expected[4];
+
+  /* Expected result for AF_INET6.  */
+  unsigned char ipv6_expected[16];
+};
+
+static void
+check_result (const char *what, const struct test_case *t, int family,
+              void *result_buffer, int inet_ret)
+{
+  TEST_VERIFY_EXIT (inet_ret >= -1);
+  TEST_VERIFY_EXIT (inet_ret <= 1);
+
+  int ok;
+  const unsigned char *expected;
+  size_t result_size;
+  switch (family)
+    {
+    case AF_INET:
+      ok = t->ipv4_ok;
+      expected = t->ipv4_expected;
+      result_size = 4;
+      break;
+    case AF_INET6:
+      ok = t->ipv6_ok;
+      expected = t->ipv6_expected;
+      result_size = 16;
+      break;
+    default:
+      FAIL_EXIT1 ("invalid address family %d", family);
+    }
+
+  if (inet_ret != ok)
+    {
+      support_record_failure ();
+      printf ("error: %s return value mismatch for [[%s]], family %d\n"
+              "  expected: %d\n"
+              "  actual: %d\n",
+              what, t->input, family, ok, inet_ret);
+      return;
+    }
+  if (memcmp (result_buffer, expected, result_size) != 0)
+    {
+      support_record_failure ();
+      printf ("error: %s result mismatch for [[%s]], family %d\n",
+              what, t->input, family);
+    }
+}
+
+static void
+run_one_test (const struct test_case *t)
+{
+  size_t test_len = strlen (t->input);
+
+  struct next_to_fault ntf_out4 = next_to_fault_allocate (4);
+  struct next_to_fault ntf_out6 = next_to_fault_allocate (16);
+
+  /* inet_pton requires NUL termination.  */
+  {
+    struct next_to_fault ntf_in = next_to_fault_allocate (test_len + 1);
+    memcpy (ntf_in.buffer, t->input, test_len + 1);
+    memset (ntf_out4.buffer, 0, 4);
+    check_result ("inet_pton", t, AF_INET, ntf_out4.buffer,
+                  inet_pton (AF_INET, ntf_in.buffer, ntf_out4.buffer));
+    memset (ntf_out6.buffer, 0, 16);
+    check_result ("inet_pton", t, AF_INET6, ntf_out6.buffer,
+                  inet_pton (AF_INET6, ntf_in.buffer, ntf_out6.buffer));
+    next_to_fault_free (&ntf_in);
+  }
+
+  /* __inet_pton_length does not require NUL termination.  */
+  {
+    struct next_to_fault ntf_in = next_to_fault_allocate (test_len);
+    memcpy (ntf_in.buffer, t->input, test_len);
+    memset (ntf_out4.buffer, 0, 4);
+    check_result ("__inet_pton_length", t, AF_INET, ntf_out4.buffer,
+                  __inet_pton_length (AF_INET, ntf_in.buffer, ntf_in.length,
+                                      ntf_out4.buffer));
+    memset (ntf_out6.buffer, 0, 16);
+    check_result ("__inet_pton_length", t, AF_INET6, ntf_out6.buffer,
+                  __inet_pton_length (AF_INET6, ntf_in.buffer, ntf_in.length,
+                                      ntf_out6.buffer));
+    next_to_fault_free (&ntf_in);
+  }
+
+  next_to_fault_free (&ntf_out4);
+  next_to_fault_free (&ntf_out6);
+}
+
+/* The test cases were manually crafted and the set enhanced with
+   American Fuzzy Lop.  */
+const struct test_case test_cases[] =
+  {
+    {.input = ".:", },
+    {.input = "0.0.0.0",
+     .ipv4_ok = true,
+     .ipv4_expected = {0, 0, 0, 0},
+    },
+    {.input = "0.:", },
+    {.input = "00", },
+    {.input = "0000000", },
+    {.input = "00000000000000000", },
+    {.input = "092.", },
+    {.input = "10.0.301.2", },
+    {.input = "127.0.0.1",
+     .ipv4_ok = true,
+     .ipv4_expected = {127, 0, 0, 1},
+    },
+    {.input = "19..", },
+    {.input = "192.0.2.-1", },
+    {.input = "192.0.2.01", },
+    {.input = "192.0.2.1.", },
+    {.input = "192.0.2.1192.", },
+    {.input = "192.0.2.192.\377..", },
+    {.input = "192.0.2.256", },
+    {.input = "192.0.2.27",
+     .ipv4_ok = true,
+     .ipv4_expected = {192, 0, 2, 27},
+    },
+    {.input = "192.0.201.", },
+    {.input = "192.0.261.", },
+    {.input = "192.0.2\256", },
+    {.input = "192.0.\262.", },
+    {.input = "192.062.", },
+    {.input = "192.092.\256", },
+    {.input = "192.0\2562.", },
+    {.input = "192.192.0.2661\031", },
+    {.input = "192.192.00n2.1.", },
+    {.input = "192.192.2.190.", },
+    {.input = "192.255.255.2555", },
+    {.input = "192.92.219\023.", },
+    {.input = "192.\260.2.", },
+    {.input = "1:1::1:1",
+     .ipv6_ok = true,
+     .ipv6_expected = {
+       0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0,
+       0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1
+     },
+    },
+    {.input = "2", },
+    {.input = "2.", },
+    {.input = "2001:db8:00001::f",
+     .ipv6_ok = true,
+     .ipv6_expected = {
+       0x20, 0x1, 0xd, 0xb8, 0x0, 0x1, 0x0, 0x0,
+       0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf
+     },
+    },
+    {.input = "2001:db8:10000::f", },
+    {.input = "2001:db8:1234:5678:abcd:ef01:2345:67",
+     .ipv6_ok = true,
+     .ipv6_expected = {
+       0x20, 0x1, 0xd, 0xb8, 0x12, 0x34, 0x56, 0x78,
+       0xab, 0xcd, 0xef, 0x1, 0x23, 0x45, 0x0, 0x67
+     },
+    },
+    {.input = "2001:db8:1234:5678:abcd:ef01:2345:6789:1", },
+    {.input = "2001:db8:1234:5678:abcd:ef01:2345::6789", },
+    {.input = "2001:db8::0",
+     .ipv6_ok = true,
+     .ipv6_expected = {
+       0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
+       0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
+     },
+    },
+    {.input = "2001:db8::00",
+     .ipv6_ok = true,
+     .ipv6_expected = {
+       0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
+       0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
+     },
+    },
+    {.input = "2001:db8::1",
+     .ipv6_ok = true,
+     .ipv6_expected = {
+       0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
+       0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1
+     },
+    },
+    {.input = "2001:db8::10",
+     .ipv6_ok = true,
+     .ipv6_expected = {
+       0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
+       0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10
+     },
+    },
+    {.input = "2001:db8::19",
+     .ipv6_ok = true,
+     .ipv6_expected = {
+       0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
+       0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x19
+     },
+    },
+    {.input = "2001:db8::1::\012", },
+    {.input = "2001:db8::1::2\012", },
+    {.input = "2001:db8::2",
+     .ipv6_ok = true,
+     .ipv6_expected = {
+       0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
+       0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2
+     },
+    },
+    {.input = "2001:db8::3",
+     .ipv6_ok = true,
+     .ipv6_expected = {
+       0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
+       0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3
+     },
+    },
+    {.input = "2001:db8::4",
+     .ipv6_ok = true,
+     .ipv6_expected = {
+       0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
+       0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4
+     },
+    },
+    {.input = "2001:db8::5",
+     .ipv6_ok = true,
+     .ipv6_expected = {
+       0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
+       0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5
+     },
+    },
+    {.input = "2001:db8::6",
+     .ipv6_ok = true,
+     .ipv6_expected = {
+       0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
+       0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6
+     },
+    },
+    {.input = "2001:db8::7",
+     .ipv6_ok = true,
+     .ipv6_expected = {
+       0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
+       0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7
+     },
+    },
+    {.input = "2001:db8::8",
+     .ipv6_ok = true,
+     .ipv6_expected = {
+       0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
+       0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8
+     },
+    },
+    {.input = "2001:db8::9",
+     .ipv6_ok = true,
+     .ipv6_expected = {
+       0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
+       0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9
+     },
+    },
+    {.input = "2001:db8::A",
+     .ipv6_ok = true,
+     .ipv6_expected = {
+       0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
+       0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa
+     },
+    },
+    {.input = "2001:db8::B",
+     .ipv6_ok = true,
+     .ipv6_expected = {
+       0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
+       0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb
+     },
+    },
+    {.input = "2001:db8::C",
+     .ipv6_ok = true,
+     .ipv6_expected = {
+       0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
+       0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc
+     },
+    },
+    {.input = "2001:db8::D",
+     .ipv6_ok = true,
+     .ipv6_expected = {
+       0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
+       0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd
+     },
+    },
+    {.input = "2001:db8::E",
+     .ipv6_ok = true,
+     .ipv6_expected = {
+       0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
+       0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe
+     },
+    },
+    {.input = "2001:db8::F",
+     .ipv6_ok = true,
+     .ipv6_expected = {
+       0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
+       0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf
+     },
+    },
+    {.input = "2001:db8::a",
+     .ipv6_ok = true,
+     .ipv6_expected = {
+       0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
+       0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa
+     },
+    },
+    {.input = "2001:db8::b",
+     .ipv6_ok = true,
+     .ipv6_expected = {
+       0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
+       0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb
+     },
+    },
+    {.input = "2001:db8::c",
+     .ipv6_ok = true,
+     .ipv6_expected = {
+       0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
+       0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc
+     },
+    },
+    {.input = "2001:db8::d",
+     .ipv6_ok = true,
+     .ipv6_expected = {
+       0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
+       0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd
+     },
+    },
+    {.input = "2001:db8::e",
+     .ipv6_ok = true,
+     .ipv6_expected = {
+       0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
+       0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe
+     },
+    },
+    {.input = "2001:db8::f",
+     .ipv6_ok = true,
+     .ipv6_expected = {
+       0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
+       0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf
+     },
+    },
+    {.input = "2001:db8::ff",
+     .ipv6_ok = true,
+     .ipv6_expected = {
+       0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
+       0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff
+     },
+    },
+    {.input = "2001:db8::ffff:2\012", },
+    {.input = "22", },
+    {.input = "2222@", },
+    {.input = "255.255.255.255",
+     .ipv4_ok = true,
+     .ipv4_expected = {255, 255, 255, 255},
+    },
+    {.input = "255.255.255.255\001", },
+    {.input = "255.255.255.25555", },
+    {.input = "2:", },
+    {.input = "2:a:8:EEEE::EEEE:F:EEE8:EEEE\034*:", },
+    {.input = "2:ff:1:1:7:ff:1:1:7.", },
+    {.input = "2f:0000000000000000000000000000000000000000000000000000000000"
+     "0000000000000000000000000000000000000000000000000000000000000000000000"
+     "0G01",
+    },
+    {.input = "429495", },
+    {.input = "5::5::", },
+    {.input = "6.6.", },
+    {.input = "992.", },
+    {.input = "::",
+     .ipv6_ok = true,
+     .ipv6_expected = {
+       0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+       0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
+     },
+    },
+    {.input = "::00001",
+     .ipv6_ok = true,
+     .ipv6_expected = {
+       0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+       0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1
+     },
+    },
+    {.input = "::1",
+     .ipv6_ok = true,
+     .ipv6_expected = {
+       0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+       0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1
+     },
+    },
+    {.input = "::10000", },
+    {.input = "::1:1",
+     .ipv6_ok = true,
+     .ipv6_expected = {
+       0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+       0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1
+     },
+    },
+    {.input = "::ff:1:1:7.0.0.1",
+     .ipv6_ok = true,
+     .ipv6_expected = {
+       0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff,
+       0x0, 0x1, 0x0, 0x1, 0x7, 0x0, 0x0, 0x1
+     },
+    },
+    {.input = "::ff:1:1:7:ff:1:1:7.", },
+    {.input = "::ff:1:1:7ff:1:8:7.0.0.1", },
+    {.input = "::ff:1:1:7ff:1:8f:1:1:71", },
+    {.input = "::ffff:02fff:127.0.S1", },
+    {.input = "::ffff:127.0.0.1",
+     .ipv6_ok = true,
+     .ipv6_expected = {
+       0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+       0x0, 0x0, 0xff, 0xff, 0x7f, 0x0, 0x0, 0x1
+     },
+    },
+    {.input = "::ffff:1:7.0.0.1",
+     .ipv6_ok = true,
+     .ipv6_expected = {
+       0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+       0xff, 0xff, 0x0, 0x1, 0x7, 0x0, 0x0, 0x1
+     },
+    },
+    {.input = ":\272", },
+    {.input = "A:f:ff:1:1:D:ff:1:1::7.", },
+    {.input = "AAAAA.", },
+    {.input = "D:::", },
+    {.input = "DF8F", },
+    {.input = "F::",
+     .ipv6_ok = true,
+     .ipv6_expected = {
+       0x0, 0xf, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+       0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
+     },
+    },
+    {.input = "F:A:8:EEEE:8:EEEE\034*:", },
+    {.input = "F:a:8:EEEE:8:EEEE\034*:", },
+    {.input = "F:ff:100:7ff:1:8:7.0.10.1",
+     .ipv6_ok = true,
+     .ipv6_expected = {
+       0x0, 0xf, 0x0, 0xff, 0x1, 0x0, 0x7, 0xff,
+       0x0, 0x1, 0x0, 0x8, 0x7, 0x0, 0xa, 0x1
+     },
+    },
+    {.input = "d92.", },
+    {.input = "ff:00000000000000000000000000000000000000000000000000000000000"
+     "00000000000000000000000000000000000000000000000000000000000000000001",
+    },
+    {.input = "fff2:2::ff2:2:f7",
+     .ipv6_ok = true,
+     .ipv6_expected = {
+       0xff, 0xf2, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0,
+       0x0, 0x0, 0xf, 0xf2, 0x0, 0x2, 0x0, 0xf7
+     },
+    },
+    {.input = "ffff:ff:ff:fff:ff:ff:ff:", },
+    {.input = "\272:", },
+    {NULL}
+  };
+
+static int
+do_test (void)
+{
+  for (size_t i = 0; test_cases[i].input != NULL; ++i)
+    run_one_test (test_cases + i);
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/support/Makefile b/support/Makefile
index a2480cd..423538d 100644
--- a/support/Makefile
+++ b/support/Makefile
@@ -74,6 +74,7 @@ libsupport-routines = \
   xmemstream \
   xmkdir \
   xmmap \
+  xmprotect \
   xmunmap \
   xopen \
   xpipe \
diff --git a/support/xmprotect.c b/support/xmprotect.c
new file mode 100644
index 0000000..9410251
--- /dev/null
+++ b/support/xmprotect.c
@@ -0,0 +1,28 @@
+/* mprotect with error checking.
+   Copyright (C) 2017 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 <support/check.h>
+#include <support/xunistd.h>
+#include <sys/mman.h>
+
+void
+xmprotect (void *addr, size_t length, int prot)
+{
+  if (mprotect (addr, length, prot) != 0)
+    FAIL_EXIT1 ("mprotect (%p, %zu, 0x%x): %m", addr, length, prot);
+}
diff --git a/support/xunistd.h b/support/xunistd.h
index 151d743..c947bfd 100644
--- a/support/xunistd.h
+++ b/support/xunistd.h
@@ -48,7 +48,7 @@ void xwrite (int, const void *, size_t);
 
 /* Invoke mmap with a zero file offset.  */
 void *xmmap (void *addr, size_t length, int prot, int flags, int fd);
-
+void xmprotect (void *addr, size_t length, int prot);
 void xmunmap (void *addr, size_t length);
 
 __END_DECLS

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog                        |   18 ++
 resolv/Makefile                  |    3 +
 resolv/Versions                  |    1 +
 resolv/inet_pton.c               |  159 ++++++-----
 resolv/resolv-internal.h         |    9 +
 resolv/tst-inet_pton.c           |  549 ++++++++++++++++++++++++++++++++++++++
 support/Makefile                 |    1 +
 support/{xdup2.c => xmprotect.c} |   12 +-
 support/xunistd.h                |    2 +-
 9 files changed, 675 insertions(+), 79 deletions(-)
 create mode 100644 resolv/tst-inet_pton.c
 copy support/{xdup2.c => xmprotect.c} (79%)


hooks/post-receive
-- 
GNU C Library master sources


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]