[COMMITTED] resolv: Remove RES_USEBSTRING and its implementation [BZ #20629]

Message ID 20161007154757.6466E43982F21@oldenburg.str.redhat.com
State Committed
Headers

Commit Message

Florian Weimer Oct. 7, 2016, 3:47 p.m. UTC
  In ns_name_ntop, the NS_CMPRSFLGS check is no longer needed because
labellen (called earlier) already rejects everything which is not
a plain label (compression references and extended label types).

2016-10-07  Florian Weimer  <fweimer@redhat.com>

	[BZ #20629]
	resolv: Remove RES_USEBSTRING and its implementation.
	* resolv/resolv.h (RES_USEBSTRING): Remove.
	* resolv/ns_name.c (NS_TYPE_ELT, DNS_LABELTYPE_BITSTRING)
	(digitvalue, encode_bitstring, decode_bitstring): Remove.
	(ns_name_ntop, ns_name_pton, ns_name_unpack, ns_name_skip)
	(labellen): Remove extended label types support.
	* resolv/res_debug.c (p_option): Remove RES_USEBSTRING handling.
	* resolv/res_init.c (res_setoptions): Likewise.
	* resolv/nss_dns/dns-host.c (_nss_dns_gethostbyaddr2_r): Likewise.
  

Patch

diff --git a/NEWS b/NEWS
index 49b9180..3b46fb1 100644
--- a/NEWS
+++ b/NEWS
@@ -64,6 +64,11 @@  Version 2.25
   “no-ip6-dotint” had already been the default, and support for the
   “ip6-dotint” option was removed from the Internet in 2006.
 
+* The "ip6-bytestring" resolver option and the corresponding RES_NOIP6DOTINT
+  flag from <resolv.h> have been removed.  The option relied on a
+  backwards-incompatible DNS extension which was never deployed on the
+  Internet.
+
 * The flags RES_AAONLY, RES_PRIMARY, RES_NOCHECKNAME, RES_KEEPTSIG defined
   in the <resolv.h> header file have been deprecated.  They were already
   unimplemented.
diff --git a/resolv/ns_name.c b/resolv/ns_name.c
index 65e7fc8..0d76fe5 100644
--- a/resolv/ns_name.c
+++ b/resolv/ns_name.c
@@ -29,32 +29,10 @@ 
 
 # define SPRINTF(x) ((size_t)sprintf x)
 
-#define NS_TYPE_ELT			0x40 /*%< EDNS0 extended label type */
-#define DNS_LABELTYPE_BITSTRING		0x41
-
 /* Data. */
 
 static const char	digits[] = "0123456789";
 
-static const char digitvalue[256] = {
-	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*16*/
-	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*32*/
-	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*48*/
-         0,  1,  2,  3,  4,  5,  6,  7,  8,  9, -1, -1, -1, -1, -1, -1, /*64*/
-	-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*80*/
-	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*96*/
-	-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*112*/
-	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*128*/
-	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*256*/
-};
-
 /* Forward. */
 
 static int		special(int);
@@ -62,12 +40,7 @@  static int		printable(int);
 static int		dn_find(const u_char *, const u_char *,
 				const u_char * const *,
 				const u_char * const *);
-static int		encode_bitstring(const char **, const char *,
-					 unsigned char **, unsigned char **,
-					 unsigned const char *);
 static int		labellen(const u_char *);
-static int		decode_bitstring(const unsigned char **,
-					 char *, const char *);
 
 /* Public. */
 
@@ -115,22 +88,6 @@  ns_name_ntop(const u_char *src, char *dst, size_t dstsiz)
 			__set_errno (EMSGSIZE);
 			return (-1);
 		}
-		if ((n & NS_CMPRSFLGS) == NS_TYPE_ELT) {
-			int m;
-
-			if (n != DNS_LABELTYPE_BITSTRING) {
-				/* XXX: labellen should reject this case */
-				__set_errno (EINVAL);
-				return(-1);
-			}
-			if ((m = decode_bitstring(&cp, dn, eom)) < 0)
-			{
-				__set_errno (EMSGSIZE);
-				return(-1);
-			}
-			dn += m;
-			continue;
-		}
 		for ((void)NULL; l > 0; l--) {
 			c = *cp++;
 			if (special(c)) {
@@ -192,7 +149,7 @@  int
 ns_name_pton(const char *src, u_char *dst, size_t dstsiz)
 {
 	u_char *label, *bp, *eom;
-	int c, n, escaped, e = 0;
+	int c, n, escaped;
 	char *cp;
 
 	escaped = 0;
@@ -202,28 +159,7 @@  ns_name_pton(const char *src, u_char *dst, size_t dstsiz)
 
 	while ((c = *src++) != 0) {
 		if (escaped) {
-			if (c == '[') { /*%< start a bit string label */
-				if ((cp = strchr(src, ']')) == NULL) {
-					__set_errno (EINVAL);
-					return(-1);
-				}
-				if ((e = encode_bitstring(&src, cp + 2,
-							  &label, &bp, eom))
-				    != 0) {
-					__set_errno (e);
-					return(-1);
-				}
-				escaped = 0;
-				label = bp++;
-				if ((c = *src++) == 0)
-					goto done;
-				else if (c != '.') {
-					__set_errno (EINVAL);
-					return(-1);
-				}
-				continue;
-			}
-			else if ((cp = strchr(digits, c)) != NULL) {
+			if ((cp = strchr(digits, c)) != NULL) {
 				n = (cp - digits) * 100;
 				if ((c = *src++) == 0 ||
 				    (cp = strchr(digits, c)) == NULL) {
@@ -291,7 +227,6 @@  ns_name_pton(const char *src, u_char *dst, size_t dstsiz)
 		__set_errno (EMSGSIZE);
 		return (-1);
 	}
-  done:
 	if (label >= eom) {
 		__set_errno (EMSGSIZE);
 		return (-1);
@@ -394,7 +329,6 @@  ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src,
 		/* Check for indirection. */
 		switch (n & NS_CMPRSFLGS) {
 		case 0:
-		case NS_TYPE_ELT:
 			/* Limit checks. */
 			if ((l = labellen(srcp - 1)) < 0) {
 				__set_errno (EMSGSIZE);
@@ -639,7 +573,6 @@  ns_name_skip(const u_char **ptrptr, const u_char *eom)
 {
 	const u_char *cp;
 	u_int n;
-	int l;
 
 	cp = *ptrptr;
 	while (cp < eom && (n = *cp++) != 0) {
@@ -648,13 +581,6 @@  ns_name_skip(const u_char **ptrptr, const u_char *eom)
 		case 0:			/*%< normal case, n == len */
 			cp += n;
 			continue;
-		case NS_TYPE_ELT: /*%< EDNS0 extended label */
-			if ((l = labellen(cp - 1)) < 0) {
-				__set_errno (EMSGSIZE);
-				return(-1);
-			}
-			cp += l;
-			continue;
 		case NS_CMPRSFLGS:	/*%< indirection */
 			cp++;
 			break;
@@ -791,180 +717,14 @@  dn_find(const u_char *domain, const u_char *msg,
 	return (-1);
 }
 
+/* Return the length of the encoded label starting at LP, or -1 for
+   compression references and extended label types.  */
 static int
-decode_bitstring(const unsigned char **cpp, char *dn, const char *eom)
+labellen (const unsigned char *lp)
 {
-	const unsigned char *cp = *cpp;
-	char *beg = dn, tc;
-	int b, blen, plen, i;
-
-	if ((blen = (*cp & 0xff)) == 0)
-		blen = 256;
-	plen = (blen + 3) / 4;
-	plen += sizeof("\\[x/]") + (blen > 99 ? 3 : (blen > 9) ? 2 : 1);
-	if (dn + plen >= eom)
-		return(-1);
-
-	cp++;
-	i = SPRINTF((dn, "\\[x"));
-	if (i < 0)
-		return (-1);
-	dn += i;
-	for (b = blen; b > 7; b -= 8, cp++) {
-		i = SPRINTF((dn, "%02x", *cp & 0xff));
-		if (i < 0)
-			return (-1);
-		dn += i;
-	}
-	if (b > 4) {
-		tc = *cp++;
-		i = SPRINTF((dn, "%02x", tc & (0xff << (8 - b))));
-		if (i < 0)
-			return (-1);
-		dn += i;
-	} else if (b > 0) {
-		tc = *cp++;
-		i = SPRINTF((dn, "%1x",
-			       ((tc >> 4) & 0x0f) & (0x0f << (4 - b))));
-		if (i < 0)
-			return (-1);
-		dn += i;
-	}
-	i = SPRINTF((dn, "/%d]", blen));
-	if (i < 0)
-		return (-1);
-	dn += i;
-
-	*cpp = cp;
-	return(dn - beg);
-}
-
-static int
-encode_bitstring(const char **bp, const char *end, unsigned char **labelp,
-		 unsigned char ** dst, unsigned const char *eom)
-{
-	int afterslash = 0;
-	const char *cp = *bp;
-	unsigned char *tp;
-	char c;
-	const char *beg_blen;
-	char *end_blen = NULL;
-	int value = 0, count = 0, tbcount = 0, blen = 0;
-
-	beg_blen = end_blen = NULL;
-
-	/* a bitstring must contain at least 2 characters */
-	if (end - cp < 2)
-		return(EINVAL);
-
-	/* XXX: currently, only hex strings are supported */
-	if (*cp++ != 'x')
-		return(EINVAL);
-	if (!isxdigit((*cp) & 0xff)) /*%< reject '\[x/BLEN]' */
-		return(EINVAL);
-
-	for (tp = *dst + 1; cp < end && tp < eom; cp++) {
-		switch((c = *cp)) {
-		case ']':	/*%< end of the bitstring */
-			if (afterslash) {
-				if (beg_blen == NULL)
-					return(EINVAL);
-				blen = (int)strtol(beg_blen, &end_blen, 10);
-				if (*end_blen != ']')
-					return(EINVAL);
-			}
-			if (count)
-				*tp++ = ((value << 4) & 0xff);
-			cp++;	/*%< skip ']' */
-			goto done;
-		case '/':
-			afterslash = 1;
-			break;
-		default:
-			if (afterslash) {
-				if (!isdigit(c&0xff))
-					return(EINVAL);
-				if (beg_blen == NULL) {
-
-					if (c == '0') {
-						/* blen never begings with 0 */
-						return(EINVAL);
-					}
-					beg_blen = cp;
-				}
-			} else {
-				if (!isxdigit(c&0xff))
-					return(EINVAL);
-				value <<= 4;
-				value += digitvalue[(int)c];
-				count += 4;
-				tbcount += 4;
-				if (tbcount > 256)
-					return(EINVAL);
-				if (count == 8) {
-					*tp++ = value;
-					count = 0;
-				}
-			}
-			break;
-		}
-	}
-  done:
-	if (cp >= end || tp >= eom)
-		return(EMSGSIZE);
-
-	/*
-	 * bit length validation:
-	 * If a <length> is present, the number of digits in the <bit-data>
-	 * MUST be just sufficient to contain the number of bits specified
-	 * by the <length>. If there are insignificant bits in a final
-	 * hexadecimal or octal digit, they MUST be zero.
-	 * RFC2673, Section 3.2.
-	 */
-	if (blen > 0) {
-		int traillen;
-
-		if (((blen + 3) & ~3) != tbcount)
-			return(EINVAL);
-		traillen = tbcount - blen; /*%< between 0 and 3 */
-		if (((value << (8 - traillen)) & 0xff) != 0)
-			return(EINVAL);
-	}
-	else
-		blen = tbcount;
-	if (blen == 256)
-		blen = 0;
-
-	/* encode the type and the significant bit fields */
-	**labelp = DNS_LABELTYPE_BITSTRING;
-	**dst = blen;
-
-	*bp = cp;
-	*dst = tp;
-
-	return(0);
-}
-
-static int
-labellen(const u_char *lp)
-{
-	int bitlen;
-	u_char l = *lp;
-
-	if ((l & NS_CMPRSFLGS) == NS_CMPRSFLGS) {
-		/* should be avoided by the caller */
-		return(-1);
-	}
-
-	if ((l & NS_CMPRSFLGS) == NS_TYPE_ELT) {
-		if (l == DNS_LABELTYPE_BITSTRING) {
-			if ((bitlen = *(lp + 1)) == 0)
-				bitlen = 256;
-			return((bitlen + 7 ) / 8 + 1);
-		}
-		return(-1);	/*%< unknwon ELT */
-	}
-	return(l);
+  if (*lp <= 63)
+    return *lp;
+  return -1;
 }
 
 /*! \file */
diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
index b6245ad..c1333b8 100644
--- a/resolv/nss_dns/dns-host.c
+++ b/resolv/nss_dns/dns-host.c
@@ -464,19 +464,6 @@  _nss_dns_gethostbyaddr2_r (const void *addr, socklen_t len, int af,
 	       (uaddr[2] & 0xff), (uaddr[1] & 0xff), (uaddr[0] & 0xff));
       break;
     case AF_INET6:
-      /* Only lookup with the byte string format if the user wants it.  */
-      if (__glibc_unlikely (_res.options & RES_USEBSTRING))
-	{
-	  qp = stpcpy (qbuf, "\\[x");
-	  for (n = 0; n < IN6ADDRSZ; ++n)
-	    qp += sprintf (qp, "%02hhx", uaddr[n]);
-	  strcpy (qp, "].ip6.arpa");
-	  n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR,
-				 host_buffer.buf->buf, 1024, &host_buffer.ptr,
-				 NULL, NULL, NULL, NULL);
-	  if (n >= 0)
-	    goto got_it_already;
-	}
       qp = qbuf;
       for (n = IN6ADDRSZ - 1; n >= 0; n--)
 	{
@@ -504,7 +491,6 @@  _nss_dns_gethostbyaddr2_r (const void *addr, socklen_t len, int af,
       return errno == ECONNREFUSED ? NSS_STATUS_UNAVAIL : NSS_STATUS_NOTFOUND;
     }
 
- got_it_already:
   status = getanswer_r (host_buffer.buf, n, qbuf, T_PTR, result, buffer, buflen,
 			errnop, h_errnop, 0 /* XXX */, ttlp, NULL);
   if (host_buffer.buf != orig_host_buffer)
diff --git a/resolv/res_debug.c b/resolv/res_debug.c
index 0404646..2cbb61c 100644
--- a/resolv/res_debug.c
+++ b/resolv/res_debug.c
@@ -558,7 +558,6 @@  p_option(u_long option) {
 	case RES_USE_INET6:	return "inet6";
 	case RES_ROTATE:	return "rotate";
 	case RES_BLAST:		return "blast";
-	case RES_USEBSTRING:	return "ip6-bytestring";
 	case RES_USE_EDNS0:	return "edns0";
 	case RES_SNGLKUP:	return "single-request";
 	case RES_SNGLKUPREOP:	return "single-request-reopen";
diff --git a/resolv/res_init.c b/resolv/res_init.c
index 12afb9e..b29c0d4 100644
--- a/resolv/res_init.c
+++ b/resolv/res_init.c
@@ -438,7 +438,6 @@  res_setoptions(res_state statp, const char *options, const char *source) {
 		  } options[] = {
 #define STRnLEN(str) str, sizeof (str) - 1
 		    { STRnLEN ("inet6"), 0, RES_USE_INET6 },
-		    { STRnLEN ("ip6-bytestring"), 0, RES_USEBSTRING },
 		    { STRnLEN ("rotate"), 0, RES_ROTATE },
 		    { STRnLEN ("edns0"), 0, RES_USE_EDNS0 },
 		    { STRnLEN ("single-request-reopen"), 0, RES_SNGLKUPREOP },
diff --git a/resolv/resolv.h b/resolv/resolv.h
index 11a7fed..1062903 100644
--- a/resolv/resolv.h
+++ b/resolv/resolv.h
@@ -197,8 +197,6 @@  struct res_sym {
 #define	RES_KEEPTSIG \
   __glibc_macro_warning ("RES_KEEPTSIG is deprecated") 0x00010000
 #define	RES_BLAST	0x00020000	/* blast all recursive servers */
-#define RES_USEBSTRING	0x00040000	/* IPv6 reverse lookup with byte
-					   strings */
 #define RES_USE_EDNS0	0x00100000	/* Use EDNS0.  */
 #define RES_SNGLKUP	0x00200000	/* one outstanding request at a time */
 #define RES_SNGLKUPREOP	0x00400000	/* -"-, but open new socket for each