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.26.9000-747-gc0a25aa


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  c0a25aa92b612786f4e45292c4aee1d7d47123f8 (commit)
      from  9e0ad3049dbae88d615bfb038e53bf365a39a634 (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=c0a25aa92b612786f4e45292c4aee1d7d47123f8

commit c0a25aa92b612786f4e45292c4aee1d7d47123f8
Author: Florian Weimer <fweimer@redhat.com>
Date:   Sat Nov 11 11:51:08 2017 +0100

    resolv: More precise checks in res_hnok, res_dnok [BZ #22409] [BZ #22412]
    
    res_hnok rejected some host names used on the Internet, such as
    www-.example.com.  res_hnok and res_dnok failed to perform basic syntax
    checking on DNS domain names.
    
    Also fix res_mailok, res_ownok.

diff --git a/ChangeLog b/ChangeLog
index 4739e62..c53ff98 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,20 @@
 2017-11-11  Florian Weimer  <fweimer@redhat.com>
 
+	[BZ #22409]
+	[BZ #22412]
+	* resolv/res_comp.c (printable_string, binary_hnok)
+	(binary_leading_dash): New functions.
+	(res_hnok): Reimplement using these functions and ns_name_pton.
+	(res_ownok): Likewise.
+	(res_mailok): Reimplement using printable_string, ns_name_pton and
+	binary_hnok.
+	(res_dnok): Reimplement using printable_string and ns_name_pton.
+	* resolv/tst-res_hnok.c (tests): Add additional tests.
+	(LETTERDIGITS, PRINTABLE): Define.
+	(do_test): Adjust one_char results.
+
+2017-11-11  Florian Weimer  <fweimer@redhat.com>
+
 	[BZ #22413]
 	* resolv/ns_name.c (ns_name_pton): Treat trailing backslash as error.
 	* resolv/tst-ns_name_pton.c (tests): Add trailing backslash tests.
diff --git a/NEWS b/NEWS
index 8e040f1..b728162 100644
--- a/NEWS
+++ b/NEWS
@@ -60,6 +60,9 @@ Deprecated and removed features, and other changes affecting compatibility:
   glibc has been removed.  The --enable-add-ons configure option is now
   ignored.
 
+* The res_hnok, res_dnok, res_mailok and res_ownok functions now check that
+  the specified string can be parsed as a domain name.
+
 Changes to build and runtime requirements:
 
   [Add changes to build and runtime requirements here]
diff --git a/resolv/res_comp.c b/resolv/res_comp.c
index 1b47a5d..c35a9fa 100644
--- a/resolv/res_comp.c
+++ b/resolv/res_comp.c
@@ -1,3 +1,21 @@
+/* Domain name processing functions.
+   Copyright (C) 1995-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) 1985, 1993
  *    The Regents of the University of California.  All rights reserved.
@@ -121,110 +139,118 @@ dn_skipname(const u_char *ptr, const u_char *eom) {
 }
 libresolv_hidden_def (dn_skipname)
 
-/*
- * Verify that a domain name uses an acceptable character set.
- */
+/* Return true if the string consists of printable ASCII characters
+   only.  */
+static bool
+printable_string (const char *dn)
+{
+  while (true)
+    {
+      char ch = *dn;
+      if (ch == '\0')
+	return true;
+      if (ch <= ' ' || ch > '~')
+	return false;
+      ++dn;
+    }
+}
 
-/*
- * Note the conspicuous absence of ctype macros in these definitions.  On
- * non-ASCII hosts, we can't depend on string literals or ctype macros to
- * tell us anything about network-format data.  The rest of the BIND system
- * is not careful about this, but for some reason, we're doing it right here.
- */
-#define PERIOD 0x2e
-#define	hyphenchar(c) ((c) == 0x2d)
-#define	underscorechar(c) ((c) == 0x5f)
-#define bslashchar(c) ((c) == 0x5c)
-#define periodchar(c) ((c) == PERIOD)
-#define asterchar(c) ((c) == 0x2a)
-#define alphachar(c) (((c) >= 0x41 && (c) <= 0x5a) \
-		   || ((c) >= 0x61 && (c) <= 0x7a))
-#define digitchar(c) ((c) >= 0x30 && (c) <= 0x39)
-
-#define borderchar(c) (alphachar(c) || digitchar(c))
-#define middlechar(c) (borderchar(c) || hyphenchar(c) || underscorechar(c))
-#define	domainchar(c) ((c) > 0x20 && (c) < 0x7f)
+/* Return true if DN points to a name consisting only of [0-9a-zA-Z_-]
+   characters.  DN must be in DNS wire format, without
+   compression.  */
+static bool
+binary_hnok (const unsigned char *dn)
+{
+  while (true)
+    {
+      size_t label_length = *dn;
+      if (label_length == 0)
+	break;
+      ++dn;
+      const unsigned char *label_end = dn + label_length;
+      do
+	{
+	  unsigned char ch = *dn;
+	  if (!(('0' <= ch && ch <= '9')
+		|| ('A' <= ch && ch <= 'Z')
+		|| ('a' <= ch && ch <= 'z')
+		|| ch == '-' || ch == '_'))
+	    return false;
+	  ++dn;
+	}
+      while (dn < label_end);
+    }
+  return true;
+}
+
+/* Return true if the binary domain name has a first labels which
+   starts with '-'.  */
+static inline bool
+binary_leading_dash (const unsigned char *dn)
+{
+  return dn[0] > 0 && dn[1] == '-';
+}
 
+/* Return 1 if res_hnok is a valid host name.  Labels must only
+   contain [0-9a-zA-Z_-] characters, and the name must not start with
+   a '-'.  The latter is to avoid confusion with program options.  */
 int
-res_hnok(const char *dn) {
-	int pch = PERIOD, ch = *dn++;
-
-	while (ch != '\0') {
-		int nch = *dn++;
-
-		if (periodchar(ch)) {
-			(void)NULL;
-		} else if (periodchar(pch)) {
-			if (!borderchar(ch))
-				return (0);
-		} else if (periodchar(nch) || nch == '\0') {
-			if (!borderchar(ch))
-				return (0);
-		} else {
-			if (!middlechar(ch))
-				return (0);
-		}
-		pch = ch, ch = nch;
-	}
-	return (1);
+res_hnok (const char *dn)
+{
+  unsigned char buf[NS_MAXCDNAME];
+  if (!printable_string (dn)
+      || ns_name_pton (dn, buf, sizeof (buf)) < 0
+      || binary_leading_dash (buf))
+    return 0;
+  return binary_hnok (buf);
 }
 libresolv_hidden_def (res_hnok)
 
-/*
- * hostname-like (A, MX, WKS) owners can have "*" as their first label
- * but must otherwise be as a host name.
- */
+/* Hostname-like (A, MX, WKS) owners can have "*" as their first label
+   but must otherwise be as a host name.  */
 int
-res_ownok(const char *dn) {
-	if (asterchar(dn[0])) {
-		if (periodchar(dn[1]))
-			return (res_hnok(dn+2));
-		if (dn[1] == '\0')
-			return (1);
-	}
-	return (res_hnok(dn));
+res_ownok (const char *dn)
+{
+  unsigned char buf[NS_MAXCDNAME];
+  if (!printable_string (dn)
+      || ns_name_pton (dn, buf, sizeof (buf)) < 0
+      || binary_leading_dash (buf))
+    return 0;
+  if (buf[0] == 1 && buf [1] == '*')
+    /* Skip over the leading "*." part.  */
+    return binary_hnok (buf + 2);
+  else
+    return binary_hnok (buf);
 }
 
-/*
- * SOA RNAMEs and RP RNAMEs can have any printable character in their first
- * label, but the rest of the name has to look like a host name.
- */
+/* SOA RNAMEs and RP RNAMEs can have any byte in their first label,
+   but the rest of the name has to look like a host name.  */
 int
-res_mailok(const char *dn) {
-	int ch, escaped = 0;
-
-	/* "." is a valid missing representation */
-	if (*dn == '\0')
-		return (1);
-
-	/* otherwise <label>.<hostname> */
-	while ((ch = *dn++) != '\0') {
-		if (!domainchar(ch))
-			return (0);
-		if (!escaped && periodchar(ch))
-			break;
-		if (escaped)
-			escaped = 0;
-		else if (bslashchar(ch))
-			escaped = 1;
-	}
-	if (periodchar(ch))
-		return (res_hnok(dn));
-	return (0);
+res_mailok (const char *dn)
+{
+  unsigned char buf[NS_MAXCDNAME];
+  if (!printable_string (dn)
+      || ns_name_pton (dn, buf, sizeof (buf)) < 0)
+    return 0;
+  unsigned char label_length = buf[0];
+  /* "." is a valid missing representation */
+  if (label_length == 0)
+    return 1;
+  /* Skip over the first label.  */
+  unsigned char *tail = buf + 1 + label_length;
+  if (*tail == 0)
+    /* More than one label is required (except for ".").  */
+    return 0;
+  return binary_hnok (tail);
 }
 
-/*
- * This function is quite liberal, since RFC 1034's character sets are only
- * recommendations.
- */
+/* Return 1 if DN is a syntactically valid domain name.  Empty names
+   are accepted.  */
 int
-res_dnok(const char *dn) {
-	int ch;
-
-	while ((ch = *dn++) != '\0')
-		if (!domainchar(ch))
-			return (0);
-	return (1);
+res_dnok (const char *dn)
+{
+  unsigned char buf[NS_MAXCDNAME];
+  return printable_string (dn) && ns_name_pton (dn, buf, sizeof (buf)) >= 0;
 }
 libresolv_hidden_def (res_dnok)
 
diff --git a/resolv/tst-res_hnok.c b/resolv/tst-res_hnok.c
index 9c92303..314477a 100644
--- a/resolv/tst-res_hnok.c
+++ b/resolv/tst-res_hnok.c
@@ -51,19 +51,31 @@ static const struct test_case tests[] =
   {
     { "", allok },
     { ".", allok },
+    { "..", 0 },
     { "www", allnomailok },
+    { "www.", allnomailok },
     { "example", allnomailok },
     { "example.com", allok },
     { "www.example.com", allok },
     { "www.example.com.", allok },
+    { "www-.example.com.", allok },
+    { "www.-example.com.", allok },
     { "*.example.com", dnok | mailok | ownok },
     { "-v", dnok },
     { "-v.example.com", mailok | dnok },
     { "**.example.com", dnok | mailok },
+    { "www.example.com\\", 0 },
     { STRING63, allnomailok },
+    { STRING63 ".", allnomailok },
+    { STRING63 "\\.", 0 },
+    { STRING63 "z", 0 },
     { STRING63 ".example.com", allok },
     { STRING63 "." STRING63 "." STRING63 "." STRING60 "z", allok },
+    { STRING63 "." STRING63 "." STRING63 "." STRING60 "z.", allok },
+    { STRING63 "." STRING63 "." STRING63 "." STRING60 "zz", 0 },
+    { STRING63 "." STRING63 "." STRING63 "." STRING60 "zzz", 0 },
     { "hostmaster@mail.example.com", dnok | mailok },
+    { "hostmaster\\@mail.example.com", dnok | mailok },
     { "with whitespace", 0 },
     { "with\twhitespace", 0 },
     { "with\nwhitespace", 0 },
@@ -116,6 +128,12 @@ one_char (const char *prefix, const char *accepted, const char *suffix,
     }
 }
 
+#define LETTERSDIGITS \
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
+
+#define PRINTABLE \
+  "!\"#$%&'()*+,/:;<=>?@[\\]^`{|}~"
+
 static int
 do_test (void)
 {
@@ -131,20 +149,18 @@ do_test (void)
     }
 
   one_char
-    ("", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.",
-     "", "res_hnok", res_hnok);
+    ("", LETTERSDIGITS "._", "", "res_hnok", res_hnok);
   one_char
     ("middle",
-     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.-_",
+     LETTERSDIGITS ".-_\\", /* "middle\\suffix" == "middlesuffix", so good.  */
      "suffix", "res_hnok", res_hnok);
   one_char
     ("middle",
-     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.-_"
-     "!\"#$%&'()*+,/:;<=>?@[\\]^`{|}~",
+     LETTERSDIGITS ".-_" PRINTABLE,
      "suffix.example", "res_mailok", res_mailok);
   one_char
     ("mailbox.middle",
-     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.-_",
+     LETTERSDIGITS ".-_\\",
      "suffix.example", "res_mailok", res_mailok);
 
   return 0;

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

Summary of changes:
 ChangeLog             |   15 ++++
 NEWS                  |    3 +
 resolv/res_comp.c     |  208 +++++++++++++++++++++++++++---------------------
 resolv/tst-res_hnok.c |   28 +++++--
 4 files changed, 157 insertions(+), 97 deletions(-)


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]