public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-commits] gentoo commit in src/patchsets/glibc/2.23: 00_all_0095-rtld-Completely-ignore-LD_LIBRARY_PATH-for-AT_SECURE.patch 00_all_0096-rtld-Reject-overly-long-LD_AUDIT-path-elements.patch 00_all_0097-rtld-Reject-overly-long-LD_PRELOAD-path-elements.patch 00_all_0098-Ignore-and-remove-LD_HWCAP_MASK-for-AT_SECURE-progra.patch 00_all_0099-CVE-2015-5180-resolv-Fix-crash-with-internal-QTYPE-B.patch README.history
@ 2017-06-19 16:43 Matthias Maier (tamiko)
  0 siblings, 0 replies; only message in thread
From: Matthias Maier (tamiko) @ 2017-06-19 16:43 UTC (permalink / raw
  To: gentoo-commits

tamiko      17/06/19 16:43:43

  Modified:             README.history
  Added:               
                        00_all_0095-rtld-Completely-ignore-LD_LIBRARY_PATH-for-AT_SECURE.patch
                        00_all_0096-rtld-Reject-overly-long-LD_AUDIT-path-elements.patch
                        00_all_0097-rtld-Reject-overly-long-LD_PRELOAD-path-elements.patch
                        00_all_0098-Ignore-and-remove-LD_HWCAP_MASK-for-AT_SECURE-progra.patch
                        00_all_0099-CVE-2015-5180-resolv-Fix-crash-with-internal-QTYPE-B.patch
  Log:
  glibc-2.23: update to patchset 8

Revision  Changes    Path
1.9                  src/patchsets/glibc/2.23/README.history

file : http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.23/README.history?rev=1.9&view=markup
plain: http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.23/README.history?rev=1.9&content-type=text/plain
diff : http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.23/README.history?r1=1.8&r2=1.9

Index: README.history
===================================================================
RCS file: /var/cvsroot/gentoo/src/patchsets/glibc/2.23/README.history,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- README.history	8 Dec 2016 19:28:34 -0000	1.8
+++ README.history	19 Jun 2017 16:43:43 -0000	1.9
@@ -1,3 +1,10 @@
+8       08 Jun 2017
+    + 00_all_0095-rtld-Completely-ignore-LD_LIBRARY_PATH-for-AT_SECURE.patch
+    + 00_all_0096-rtld-Reject-overly-long-LD_AUDIT-path-elements.patch
+    + 00_all_0097-rtld-Reject-overly-long-LD_PRELOAD-path-elements.patch
+    + 00_all_0098-Ignore-and-remove-LD_HWCAP_MASK-for-AT_SECURE-progra.patch
+    + 00_all_0099-CVE-2015-5180-resolv-Fix-crash-with-internal-QTYPE-B.patch
+
 7		08 Dec 2016
 	+ 00_all_0090-MIPS-Add-.insn-to-ensure-a-text-label-is-defined-as-.patch
 	+ 00_all_0091-alpha-fix-ceil-on-sNaN-input.patch



1.1                  src/patchsets/glibc/2.23/00_all_0095-rtld-Completely-ignore-LD_LIBRARY_PATH-for-AT_SECURE.patch

file : http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.23/00_all_0095-rtld-Completely-ignore-LD_LIBRARY_PATH-for-AT_SECURE.patch?rev=1.1&view=markup
plain: http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.23/00_all_0095-rtld-Completely-ignore-LD_LIBRARY_PATH-for-AT_SECURE.patch?rev=1.1&content-type=text/plain

Index: 00_all_0095-rtld-Completely-ignore-LD_LIBRARY_PATH-for-AT_SECURE.patch
===================================================================
From 4d009d39ac9ede0369e268554a181b428f177a80 Mon Sep 17 00:00:00 2001
Message-Id: <4d009d39ac9ede0369e268554a181b428f177a80.1495998948.git.fweimer@redhat.com>
In-Reply-To: <cover.1495998948.git.fweimer@redhat.com>
References: <cover.1495998948.git.fweimer@redhat.com>
From: Florian Weimer <fweimer@redhat.com>
Date: Sun, 28 May 2017 20:37:40 +0200
Subject: [PATCH 1/3] rtld: Completely ignore LD_LIBRARY_PATH for AT_SECURE=1
 programs
To: libc-alpha@sourceware.org

LD_LIBRARY_PATH can only be used to reorder system search paths, which
is not useful functionality.
---
 elf/rtld.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/elf/rtld.c b/elf/rtld.c
index 319ef06..824b6cf 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -2419,7 +2419,8 @@ process_envvars (enum mode *modep)
 
 	case 12:
 	  /* The library search path.  */
-	  if (memcmp (envline, "LIBRARY_PATH", 12) == 0)
+	  if (!__libc_enable_secure
+	      && memcmp (envline, "LIBRARY_PATH", 12) == 0)
 	    {
 	      library_path = &envline[13];
 	      break;
-- 
2.9.4




1.1                  src/patchsets/glibc/2.23/00_all_0096-rtld-Reject-overly-long-LD_AUDIT-path-elements.patch

file : http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.23/00_all_0096-rtld-Reject-overly-long-LD_AUDIT-path-elements.patch?rev=1.1&view=markup
plain: http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.23/00_all_0096-rtld-Reject-overly-long-LD_AUDIT-path-elements.patch?rev=1.1&content-type=text/plain

Index: 00_all_0096-rtld-Reject-overly-long-LD_AUDIT-path-elements.patch
===================================================================
From ba67ba3275d47e0080f0e5f09d9f5102c000c97e Mon Sep 17 00:00:00 2001
Message-Id: <ba67ba3275d47e0080f0e5f09d9f5102c000c97e.1495998948.git.fweimer@redhat.com>
In-Reply-To: <cover.1495998948.git.fweimer@redhat.com>
References: <cover.1495998948.git.fweimer@redhat.com>
From: Florian Weimer <fweimer@redhat.com>
Date: Sun, 28 May 2017 20:44:52 +0200
Subject: [PATCH 3/3] rtld: Reject overly long LD_AUDIT path elements
To: libc-alpha@sourceware.org

Also only process the last LD_AUDIT entry.
---
 elf/rtld.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 95 insertions(+), 15 deletions(-)

diff --git a/elf/rtld.c b/elf/rtld.c
index 215a9ae..511c6bf 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -100,13 +100,91 @@ strong_alias (__pointer_chk_guard_local, __pointer_chk_guard)
 #endif
 
 
-/* List of auditing DSOs.  */
+/* LD_AUDIT variable contents.  Must be processed before the
+   audit_list below.  */
+const char *audit_list_string;
+
+/* Cyclic list of auditing DSOs.  audit_list->next is the first
+   element.  */
 static struct audit_list
 {
   const char *name;
   struct audit_list *next;
 } *audit_list;
 
+/* Iterator for audit_list_string followed by audit_list.  */
+struct audit_list_iter
+{
+  /* Tail of audit_list_string still needing processing, or NULL.  */
+  const char *audit_list_tail;
+
+  /* The list element returned in the previous iteration.  NULL before
+     the first element.  */
+  struct audit_list *previous;
+
+  /* Scratch buffer for returning a name which is part of
+     audit_list_string.  */
+  char fname[PATH_MAX];
+};
+
+/* Initialize an audit list iterator.  */
+static void
+audit_list_iter_init (struct audit_list_iter *iter)
+{
+  iter->audit_list_tail = audit_list_string;
+  iter->previous = NULL;
+}
+
+/* Iterate through both audit_list_string and audit_list.  */
+static const char *
+audit_list_iter_next (struct audit_list_iter *iter)
+{
+  if (iter->audit_list_tail != NULL)
+    {
+      /* First iterate over audit_list_string.  */
+      while (*iter->audit_list_tail != '\0')
+	{
+	  /* Split audit list at colon.  */
+	  size_t len = strcspn (iter->audit_list_tail, ":");
+	  if (len > 0 && len < PATH_MAX)
+	    {
+	      memcpy (iter->fname, iter->audit_list_tail, len);
+	      iter->fname[len] = '\0';
+	    }
+	  else
+	    /* Do not return this name to the caller.  */
+	    iter->fname[0] = '\0';
+
+	  /* Skip over the substring and the following delimiter.  */
+	  iter->audit_list_tail += len;
+	  if (*iter->audit_list_tail == ':')
+	    ++iter->audit_list_tail;
+
+	  /* If the name is valid, return it.  */
+	  if (dso_name_valid_for_suid (iter->fname))
+	    return iter->fname;
+	  /* Otherwise, wrap around and try the next name.  */
+	}
+      /* Fall through to the procesing of audit_list.  */
+    }
+
+  if (iter->previous == NULL)
+    {
+      if (audit_list == NULL)
+	/* No pre-parsed audit list.  */
+	return NULL;
+      /* Start of audit list.  The first list element is at
+	 audit_list->next (cyclic list).  */
+      iter->previous = audit_list->next;
+      return iter->previous->name;
+    }
+  if (iter->previous == audit_list)
+    /* Cyclic list wrap-around.  */
+    return NULL;
+  iter->previous = iter->previous->next;
+  return iter->previous->name;
+}
+
 #ifndef HAVE_INLINED_SYSCALLS
 /* Set nonzero during loading and initialization of executable and
    libraries, cleared before the executable's entry point runs.  This
@@ -1257,11 +1335,13 @@ of this helper program; chances are you did not intend to run this program.\n\
     GL(dl_rtld_map).l_tls_modid = _dl_next_tls_modid ();
 
   /* If we have auditing DSOs to load, do it now.  */
-  if (__glibc_unlikely (audit_list != NULL))
+  bool need_security_init = true;
+  if (__glibc_unlikely (audit_list != NULL)
+      || __glibc_unlikely (audit_list_string != NULL))
     {
-      /* Iterate over all entries in the list.  The order is important.  */
       struct audit_ifaces *last_audit = NULL;
-      struct audit_list *al = audit_list->next;
+      struct audit_list_iter al_iter;
+      audit_list_iter_init (&al_iter);
 
       /* Since we start using the auditing DSOs right away we need to
 	 initialize the data structures now.  */
@@ -1272,9 +1352,14 @@ of this helper program; chances are you did not intend to run this program.\n\
 	 use different values (especially the pointer guard) and will
 	 fail later on.  */
       security_init ();
+      need_security_init = false;
 
-      do
+      while (true)
 	{
+	  const char *name = audit_list_iter_next (&al_iter);
+	  if (name == NULL)
+	    break;
+
 	  int tls_idx = GL(dl_tls_max_dtv_idx);
 
 	  /* Now it is time to determine the layout of the static TLS
@@ -1283,7 +1368,7 @@ of this helper program; chances are you did not intend to run this program.\n\
 	     no DF_STATIC_TLS bit is set.  The reason is that we know
 	     glibc will use the static model.  */
 	  struct dlmopen_args dlmargs;
-	  dlmargs.fname = al->name;
+	  dlmargs.fname = name;
 	  dlmargs.map = NULL;
 
 	  const char *objname;
@@ -1296,7 +1381,7 @@ of this helper program; chances are you did not intend to run this program.\n\
 	    not_loaded:
 	      _dl_error_printf ("\
 ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
-				al->name, err_str);
+				name, err_str);
 	      if (malloced)
 		free ((char *) err_str);
 	    }
@@ -1400,10 +1485,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
 		  goto not_loaded;
 		}
 	    }
-
-	  al = al->next;
 	}
-      while (al != audit_list->next);
 
       /* If we have any auditing modules, announce that we already
 	 have two objects loaded.  */
@@ -1682,7 +1764,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
   if (tcbp == NULL)
     tcbp = init_tls ();
 
-  if (__glibc_likely (audit_list == NULL))
+  if (__glibc_likely (need_security_init))
     /* Initialize security features.  But only if we have not done it
        earlier.  */
     security_init ();
@@ -2313,9 +2395,7 @@ process_dl_audit (char *str)
   char *p;
 
   while ((p = (strsep) (&str, ":")) != NULL)
-    if (p[0] != '\0'
-	&& (__builtin_expect (! __libc_enable_secure, 1)
-	    || strchr (p, '/') == NULL))
+    if (dso_name_valid_for_suid (p))
       {
 	/* This is using the local malloc, not the system malloc.  The
 	   memory can never be freed.  */
@@ -2379,7 +2459,7 @@ process_envvars (enum mode *modep)
 	      break;
 	    }
 	  if (memcmp (envline, "AUDIT", 5) == 0)
-	    process_dl_audit (&envline[6]);
+	    audit_list_string = &envline[6];
 	  break;
 
 	case 7:



1.1                  src/patchsets/glibc/2.23/00_all_0097-rtld-Reject-overly-long-LD_PRELOAD-path-elements.patch

file : http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.23/00_all_0097-rtld-Reject-overly-long-LD_PRELOAD-path-elements.patch?rev=1.1&view=markup
plain: http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.23/00_all_0097-rtld-Reject-overly-long-LD_PRELOAD-path-elements.patch?rev=1.1&content-type=text/plain

Index: 00_all_0097-rtld-Reject-overly-long-LD_PRELOAD-path-elements.patch
===================================================================
From 65ff0b7a085b85271ec8fde99f542281b495e3bc Mon Sep 17 00:00:00 2001
Message-Id: <65ff0b7a085b85271ec8fde99f542281b495e3bc.1495998948.git.fweimer@redhat.com>
In-Reply-To: <cover.1495998948.git.fweimer@redhat.com>
References: <cover.1495998948.git.fweimer@redhat.com>
From: Florian Weimer <fweimer@redhat.com>
Date: Sun, 28 May 2017 20:57:40 +0200
Subject: [PATCH 2/3] rtld: Reject overly long LD_PRELOAD path elements
To: libc-alpha@sourceware.org

---
 elf/rtld.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 53 insertions(+), 16 deletions(-)

diff --git a/elf/rtld.c b/elf/rtld.c
index 215a9ae..8c41cc9 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -99,6 +99,22 @@ uintptr_t __pointer_chk_guard_local
 strong_alias (__pointer_chk_guard_local, __pointer_chk_guard)
 #endif
 
+/* Check that AT_SECURE=0, or that the passed name does not contain
+   directories and is not overly long.  Reject empty names
+   unconditionally.  */
+static bool
+dso_name_valid_for_suid (const char *p)
+{
+  if (__glibc_unlikely (__libc_enable_secure))
+    {
+      /* Ignore pathnames with directories for AT_SECURE=1
+	 programs, and also skip overlong names.  */
+      size_t len = strlen (p);
+      if (len >= NAME_MAX || memchr (p, '/', len) != NULL)
+	return false;
+    }
+  return *p != '\0';
+}
 
 /* List of auditing DSOs.  */
 static struct audit_list
@@ -730,6 +746,42 @@ static const char *preloadlist attribute_relro;
 /* Nonzero if information about versions has to be printed.  */
 static int version_info attribute_relro;
 
+/* The LD_PRELOAD environment variable gives list of libraries
+   separated by white space or colons that are loaded before the
+   executable's dependencies and prepended to the global scope list.
+   (If the binary is running setuid all elements containing a '/' are
+   ignored since it is insecure.)  Return the number of preloads
+   performed.  */
+unsigned int
+handle_ld_preload (const char *preloadlist, struct link_map *main_map)
+{
+  unsigned int npreloads = 0;
+  const char *p = preloadlist;
+  char fname[PATH_MAX];
+
+  while (*p != '\0')
+    {
+      /* Split preload list at space/colon.  */
+      size_t len = strcspn (p, " :");
+      if (len > 0 && len < PATH_MAX)
+	{
+	  memcpy (fname, p, len);
+	  fname[len] = '\0';
+	}
+      else
+	fname[0] = '\0';
+
+      /* Skip over the substring and the following delimiter.  */
+      p += len;
+      if (*p == ' ' || *p == ':')
+	++p;
+
+      if (dso_name_valid_for_suid (fname))
+	npreloads += do_preload (fname, main_map, "LD_PRELOAD");
+    }
+  return npreloads;
+}
+
 static void
 dl_main (const ElfW(Phdr) *phdr,
 	 ElfW(Word) phnum,
@@ -1481,23 +1533,8 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
 
   if (__glibc_unlikely (preloadlist != NULL))
     {
-      /* The LD_PRELOAD environment variable gives list of libraries
-	 separated by white space or colons that are loaded before the
-	 executable's dependencies and prepended to the global scope
-	 list.  If the binary is running setuid all elements
-	 containing a '/' are ignored since it is insecure.  */
-      char *list = strdupa (preloadlist);
-      char *p;
-
       HP_TIMING_NOW (start);
-
-      /* Prevent optimizing strsep.  Speed is not important here.  */
-      while ((p = (strsep) (&list, " :")) != NULL)
-	if (p[0] != '\0'
-	    && (__builtin_expect (! __libc_enable_secure, 1)
-		|| strchr (p, '/') == NULL))
-	  npreloads += do_preload (p, main_map, "LD_PRELOAD");
-
+      npreloads += handle_ld_preload (preloadlist, main_map);
       HP_TIMING_NOW (stop);
       HP_TIMING_DIFF (diff, start, stop);
       HP_TIMING_ACCUM_NT (load_time, diff);



1.1                  src/patchsets/glibc/2.23/00_all_0098-Ignore-and-remove-LD_HWCAP_MASK-for-AT_SECURE-progra.patch

file : http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.23/00_all_0098-Ignore-and-remove-LD_HWCAP_MASK-for-AT_SECURE-progra.patch?rev=1.1&view=markup
plain: http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.23/00_all_0098-Ignore-and-remove-LD_HWCAP_MASK-for-AT_SECURE-progra.patch?rev=1.1&content-type=text/plain

Index: 00_all_0098-Ignore-and-remove-LD_HWCAP_MASK-for-AT_SECURE-progra.patch
===================================================================
From 1c1243b6fc33c029488add276e56570a07803bfd Mon Sep 17 00:00:00 2001
From: Siddhesh Poyarekar <siddhesh@sourceware.org>
Date: Tue, 7 Mar 2017 20:52:04 +0530
Subject: [PATCH] Ignore and remove LD_HWCAP_MASK for AT_SECURE programs (bug
 #21209)

The LD_HWCAP_MASK environment variable may alter the selection of
function variants for some architectures.  For AT_SECURE process it
means that if an outdated routine has a bug that would otherwise not
affect newer platforms by default, LD_HWCAP_MASK will allow that bug
to be exploited.

To be on the safe side, ignore and disable LD_HWCAP_MASK for setuid
binaries.

	[BZ #21209]
	* elf/rtld.c (process_envvars): Ignore LD_HWCAP_MASK for
	AT_SECURE processes.
	* sysdeps/generic/unsecvars.h: Add LD_HWCAP_MASK.
	* elf/tst-env-setuid.c (test_parent): Test LD_HWCAP_MASK.
	(test_child): Likewise.
	* elf/Makefile (tst-env-setuid-ENV): Add LD_HWCAP_MASK.
---
 ChangeLog                   | 10 ++++++++++
 elf/Makefile                |  3 ++-
 elf/rtld.c                  |  3 ++-
 elf/tst-env-setuid.c        | 12 ++++++++++++
 sysdeps/generic/unsecvars.h |  1 +
 5 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/elf/rtld.c b/elf/rtld.c
index a036ece956..5986eaf4a1 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -2404,7 +2404,8 @@ process_envvars (enum mode *modep)
 
 	case 10:
 	  /* Mask for the important hardware capabilities.  */
-	  if (memcmp (envline, "HWCAP_MASK", 10) == 0)
+	  if (!__libc_enable_secure
+	      && memcmp (envline, "HWCAP_MASK", 10) == 0)
 	    GLRO(dl_hwcap_mask) = __strtoul_internal (&envline[11], NULL,
 						      0, 0);
 	  break;
diff --git a/sysdeps/generic/unsecvars.h b/sysdeps/generic/unsecvars.h
index a74083786e..5ea8a4a259 100644
--- a/sysdeps/generic/unsecvars.h
+++ b/sysdeps/generic/unsecvars.h
@@ -16,6 +16,7 @@
   "LD_DEBUG\0"								      \
   "LD_DEBUG_OUTPUT\0"							      \
   "LD_DYNAMIC_WEAK\0"							      \
+  "LD_HWCAP_MASK\0"							      \
   "LD_LIBRARY_PATH\0"							      \
   "LD_ORIGIN_PATH\0"							      \
   "LD_PRELOAD\0"							      \
-- 
2.13.0




1.1                  src/patchsets/glibc/2.23/00_all_0099-CVE-2015-5180-resolv-Fix-crash-with-internal-QTYPE-B.patch

file : http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.23/00_all_0099-CVE-2015-5180-resolv-Fix-crash-with-internal-QTYPE-B.patch?rev=1.1&view=markup
plain: http://sources.gentoo.org/viewvc.cgi/gentoo/src/patchsets/glibc/2.23/00_all_0099-CVE-2015-5180-resolv-Fix-crash-with-internal-QTYPE-B.patch?rev=1.1&content-type=text/plain

Index: 00_all_0099-CVE-2015-5180-resolv-Fix-crash-with-internal-QTYPE-B.patch
===================================================================
From 20f534e0abd81149c71cef082c8c058bb9d953af Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Sat, 31 Dec 2016 20:22:09 +0100
Subject: [PATCH] CVE-2015-5180: resolv: Fix crash with internal QTYPE [BZ
 #18784]

Also rename T_UNSPEC because an upcoming public header file
update will use that name.

(cherry picked from commit fc82b0a2dfe7dbd35671c10510a8da1043d746a5)
(cherry picked from commit b3b37f1a5559a7620e31c8053ed1b44f798f2b6d)
---
 include/arpa/nameser_compat.h |   6 +-
 resolv/Makefile               |   5 ++
 resolv/nss_dns/dns-host.c     |   2 +-
 resolv/res_mkquery.c          |   4 +
 resolv/res_query.c            |   6 +-
 resolv/tst-resolv-qtypes.c    | 185 ++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 201 insertions(+), 7 deletions(-)
 create mode 100644 resolv/tst-resolv-qtypes.c

diff --git a/include/arpa/nameser_compat.h b/include/arpa/nameser_compat.h
index 2e735ede4c0e..7c0deed9aed4 100644
--- a/include/arpa/nameser_compat.h
+++ b/include/arpa/nameser_compat.h
@@ -1,8 +1,8 @@
 #ifndef _ARPA_NAMESER_COMPAT_
 #include <resolv/arpa/nameser_compat.h>
 
-/* Picksome unused number to represent lookups of IPv4 and IPv6 (i.e.,
-   T_A and T_AAAA).  */
-#define T_UNSPEC 62321
+/* The number is outside the 16-bit RR type range and is used
+   internally by the implementation.  */
+#define T_QUERY_A_AND_AAAA 439963904
 
 #endif
diff --git a/resolv/Makefile b/resolv/Makefile
index 8be41d3ae141..a4c86b976257 100644
--- a/resolv/Makefile
+++ b/resolv/Makefile
@@ -40,6 +40,9 @@ ifeq ($(have-thread-library),yes)
 extra-libs += libanl
 routines += gai_sigqueue
 tests += tst-res_hconf_reorder
+
+# This test sends millions of packets and is rather slow.
+xtests += tst-resolv-qtypes
 endif
 extra-libs-others = $(extra-libs)
 libresolv-routines := gethnamaddr res_comp res_debug	\
@@ -117,3 +120,5 @@ tst-leaks2-ENV = MALLOC_TRACE=$(objpfx)tst-leaks2.mtrace
 $(objpfx)mtrace-tst-leaks2.out: $(objpfx)tst-leaks2.out
 	$(common-objpfx)malloc/mtrace $(objpfx)tst-leaks2.mtrace > $@; \
 	$(evaluate-test)
+
+$(objpfx)tst-resolv-qtypes: $(objpfx)libresolv.so $(shared-thread-library)
diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
index 5f9e35701b2a..d16fa4b8edf6 100644
--- a/resolv/nss_dns/dns-host.c
+++ b/resolv/nss_dns/dns-host.c
@@ -323,7 +323,7 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
 
   int olderr = errno;
   enum nss_status status;
-  int n = __libc_res_nsearch (&_res, name, C_IN, T_UNSPEC,
+  int n = __libc_res_nsearch (&_res, name, C_IN, T_QUERY_A_AND_AAAA,
 			      host_buffer.buf->buf, 2048, &host_buffer.ptr,
 			      &ans2p, &nans2p, &resplen2, &ans2p_malloced);
   if (n >= 0)
diff --git a/resolv/res_mkquery.c b/resolv/res_mkquery.c
index 12f9730199f8..d80b5318e5e0 100644
--- a/resolv/res_mkquery.c
+++ b/resolv/res_mkquery.c
@@ -103,6 +103,10 @@ res_nmkquery(res_state statp,
 	int n;
 	u_char *dnptrs[20], **dpp, **lastdnptr;
 
+	if (class < 0 || class > 65535
+	    || type < 0 || type > 65535)
+	  return -1;
+
 #ifdef DEBUG
 	if (statp->options & RES_DEBUG)
 		printf(";; res_nmkquery(%s, %s, %s, %s)\n",
diff --git a/resolv/res_query.c b/resolv/res_query.c
index 944d1a90f57e..07dc6f658386 100644
--- a/resolv/res_query.c
+++ b/resolv/res_query.c
@@ -122,7 +122,7 @@ __libc_res_nquery(res_state statp,
 	int n, use_malloc = 0;
 	u_int oflags = statp->_flags;
 
-	size_t bufsize = (type == T_UNSPEC ? 2 : 1) * QUERYSIZE;
+	size_t bufsize = (type == T_QUERY_A_AND_AAAA ? 2 : 1) * QUERYSIZE;
 	u_char *buf = alloca (bufsize);
 	u_char *query1 = buf;
 	int nquery1 = -1;
@@ -137,7 +137,7 @@ __libc_res_nquery(res_state statp,
 		printf(";; res_query(%s, %d, %d)\n", name, class, type);
 #endif
 
-	if (type == T_UNSPEC)
+	if (type == T_QUERY_A_AND_AAAA)
 	  {
 	    n = res_nmkquery(statp, QUERY, name, class, T_A, NULL, 0, NULL,
 			     query1, bufsize);
@@ -190,7 +190,7 @@ __libc_res_nquery(res_state statp,
 	if (__builtin_expect (n <= 0, 0) && !use_malloc) {
 		/* Retry just in case res_nmkquery failed because of too
 		   short buffer.  Shouldn't happen.  */
-		bufsize = (type == T_UNSPEC ? 2 : 1) * MAXPACKET;
+		bufsize = (type == T_QUERY_A_AND_AAAA ? 2 : 1) * MAXPACKET;
 		buf = malloc (bufsize);
 		if (buf != NULL) {
 			query1 = buf;
diff --git a/resolv/tst-resolv-qtypes.c b/resolv/tst-resolv-qtypes.c
new file mode 100644
index 000000000000..b3e60c693bf2
--- /dev/null
+++ b/resolv/tst-resolv-qtypes.c
@@ -0,0 +1,185 @@
+/* Exercise low-level query functions with different QTYPEs.
+   Copyright (C) 2016 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 <resolv.h>
+#include <string.h>
+#include <support/check.h>
+#include <support/check_nss.h>
+#include <support/resolv_test.h>
+#include <support/support.h>
+#include <support/test-driver.h>
+#include <support/xmemstream.h>
+
+/* If ture, the response function will send the actual response packet
+   over TCP instead of UDP.  */
+static volatile bool force_tcp;
+
+/* Send back a fake resource record matching the QTYPE.  */
+static void
+response (const struct resolv_response_context *ctx,
+          struct resolv_response_builder *b,
+          const char *qname, uint16_t qclass, uint16_t qtype)
+{
+  if (force_tcp && ctx->tcp)
+    {
+      resolv_response_init (b, (struct resolv_response_flags) { .tc = 1 });
+      resolv_response_add_question (b, qname, qclass, qtype);
+      return;
+    }
+
+  resolv_response_init (b, (struct resolv_response_flags) { });
+  resolv_response_add_question (b, qname, qclass, qtype);
+  resolv_response_section (b, ns_s_an);
+  resolv_response_open_record (b, qname, qclass, qtype, 0);
+  resolv_response_add_data (b, &qtype, sizeof (qtype));
+  resolv_response_close_record (b);
+}
+
+static const const char *domain = "www.example.com";
+
+static int
+wrap_res_query (int type, unsigned char *answer, int answer_length)
+{
+  return res_query (domain, C_IN, type, answer, answer_length);
+}
+
+static int
+wrap_res_search (int type, unsigned char *answer, int answer_length)
+{
+  return res_query (domain, C_IN, type, answer, answer_length);
+}
+
+static int
+wrap_res_querydomain (int type, unsigned char *answer, int answer_length)
+{
+  return res_querydomain ("www", "example.com", C_IN, type,
+                           answer, answer_length);
+}
+
+static int
+wrap_res_send (int type, unsigned char *answer, int answer_length)
+{
+  unsigned char buf[512];
+  int ret = res_mkquery (QUERY, domain, C_IN, type,
+                         (const unsigned char *) "", 0, NULL,
+                         buf, sizeof (buf));
+  if (type < 0 || type >= 65536)
+    {
+      /* res_mkquery fails for out-of-range record types.  */
+      TEST_VERIFY_EXIT (ret == -1);
+      return -1;
+    }
+  TEST_VERIFY_EXIT (ret > 12);  /* DNS header length.  */
+  return res_send (buf, ret, answer, answer_length);
+}
+
+static int
+wrap_res_nquery (int type, unsigned char *answer, int answer_length)
+{
+  return res_nquery (&_res, domain, C_IN, type, answer, answer_length);
+}
+
+static int
+wrap_res_nsearch (int type, unsigned char *answer, int answer_length)
+{
+  return res_nquery (&_res, domain, C_IN, type, answer, answer_length);
+}
+
+static int
+wrap_res_nquerydomain (int type, unsigned char *answer, int answer_length)
+{
+  return res_nquerydomain (&_res, "www", "example.com", C_IN, type,
+                           answer, answer_length);
+}
+
+static int
+wrap_res_nsend (int type, unsigned char *answer, int answer_length)
+{
+  unsigned char buf[512];
+  int ret = res_nmkquery (&_res, QUERY, domain, C_IN, type,
+                         (const unsigned char *) "", 0, NULL,
+                         buf, sizeof (buf));
+  if (type < 0 || type >= 65536)
+    {
+      /* res_mkquery fails for out-of-range record types.  */
+      TEST_VERIFY_EXIT (ret == -1);
+      return -1;
+    }
+  TEST_VERIFY_EXIT (ret > 12);  /* DNS header length.  */
+  return res_nsend (&_res, buf, ret, answer, answer_length);
+}
+
+static void
+test_function (const char *fname,
+               int (*func) (int type,
+                            unsigned char *answer, int answer_length))
+{
+  unsigned char buf[512];
+  for (int tcp = 0; tcp < 2; ++tcp)
+    {
+      force_tcp = tcp;
+      for (unsigned int type = 1; type <= 65535; ++type)
+        {
+          if (test_verbose)
+            printf ("info: sending QTYPE %d with %s (tcp=%d)\n",
+                    type, fname, tcp);
+          int ret = func (type, buf, sizeof (buf));
+          if (ret != 47)
+            FAIL_EXIT1 ("%s tcp=%d qtype=%d return value %d",
+                        fname,tcp, type, ret);
+          /* One question, one answer record.  */
+          TEST_VERIFY (memcmp (buf + 4, "\0\1\0\1\0\0\0\0", 8) == 0);
+          /* Question section.  */
+          static const char qname[] = "\3www\7example\3com";
+          size_t qname_length = sizeof (qname);
+          TEST_VERIFY (memcmp (buf + 12, qname, qname_length) == 0);
+          /* RDATA part of answer.  */
+          uint16_t type16 = type;
+          TEST_VERIFY (memcmp (buf + ret - 2, &type16, sizeof (type16)) == 0);
+        }
+    }
+
+  TEST_VERIFY (func (-1, buf, sizeof (buf) == -1));
+  TEST_VERIFY (func (65536, buf, sizeof (buf) == -1));
+}
+
+static int
+do_test (void)
+{
+  struct resolv_redirect_config config =
+    {
+      .response_callback = response,
+    };
+  struct resolv_test *obj = resolv_test_start (config);
+
+  test_function ("res_query", &wrap_res_query);
+  test_function ("res_search", &wrap_res_search);
+  test_function ("res_querydomain", &wrap_res_querydomain);
+  test_function ("res_send", &wrap_res_send);
+
+  test_function ("res_nquery", &wrap_res_nquery);
+  test_function ("res_nsearch", &wrap_res_nsearch);
+  test_function ("res_nquerydomain", &wrap_res_nquerydomain);
+  test_function ("res_nsend", &wrap_res_nsend);
+
+  resolv_test_end (obj);
+  return 0;
+}
+
+#define TIMEOUT 300
+#include <support/test-driver.c>
-- 
2.11.0






^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2017-06-19 16:44 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-06-19 16:43 [gentoo-commits] gentoo commit in src/patchsets/glibc/2.23: 00_all_0095-rtld-Completely-ignore-LD_LIBRARY_PATH-for-AT_SECURE.patch 00_all_0096-rtld-Reject-overly-long-LD_AUDIT-path-elements.patch 00_all_0097-rtld-Reject-overly-long-LD_PRELOAD-path-elements.patch 00_all_0098-Ignore-and-remove-LD_HWCAP_MASK-for-AT_SECURE-progra.patch 00_all_0099-CVE-2015-5180-resolv-Fix-crash-with-internal-QTYPE-B.patch README.history Matthias Maier (tamiko)

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox