nss_dns: Adjust ns_name_ntop calls for gethostby*, getaddrinfo

Message ID 20190308204625.7864F80DD6B5@oldenburg2.str.redhat.com
State Committed
Headers

Commit Message

Florian Weimer March 8, 2019, 8:46 p.m. UTC
  ns_name_ntop failure always means that the output buffer is not
large enough.

2019-03-08  Florian Weimer  <fweimer@redhat.com>

	* resolv/nss_dns/dns-host.c (getanswer_r, gaih_getanswer_slice):
	On ns_name_ntop failure, the buffer is always too small.
  

Patch

diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
index a18b8a6bf4..f04e08016c 100644
--- a/resolv/nss_dns/dns-host.c
+++ b/resolv/nss_dns/dns-host.c
@@ -698,23 +698,18 @@  getanswer_r (struct resolv_context *ctx,
 
   n = __ns_name_unpack (answer->buf, end_of_message, cp,
 			packtmp, sizeof packtmp);
-  if (n != -1 && __ns_name_ntop (packtmp, bp, linebuflen) == -1)
+  if (__glibc_unlikely (n < 0))
     {
-      if (__glibc_unlikely (errno == EMSGSIZE))
-	goto too_small;
-
-      n = -1;
+      *errnop = errno;
+      *h_errnop = NO_RECOVERY;
+      return NSS_STATUS_UNAVAIL;
     }
+  if (__ns_name_ntop (packtmp, bp, linebuflen) < 0)
+    goto too_small;
 
-  if (n > 0 && bp[0] == '.')
+  if (bp[0] == '.')
     bp[0] = '\0';
 
-  if (__glibc_unlikely (n < 0))
-    {
-      *errnop = errno;
-      *h_errnop = NO_RECOVERY;
-      return NSS_STATUS_UNAVAIL;
-    }
   if (__glibc_unlikely (name_ok (bp) == 0))
     {
       errno = EBADMSG;
@@ -761,15 +756,16 @@  getanswer_r (struct resolv_context *ctx,
 
       n = __ns_name_unpack (answer->buf, end_of_message, cp,
 			    packtmp, sizeof packtmp);
-      if (n != -1 && __ns_name_ntop (packtmp, bp, linebuflen) == -1)
+      if (n < 0)
 	{
-	  if (__glibc_unlikely (errno == EMSGSIZE))
-	    goto too_small;
-
-	  n = -1;
+	  ++had_error;
+	  continue;
 	}
 
-      if (__glibc_unlikely (n < 0 || (*name_ok) (bp) == 0))
+      if (__ns_name_ntop (packtmp, bp, linebuflen) < 0)
+	goto too_small;
+
+      if (__glibc_unlikely ((*name_ok) (bp) == 0))
 	{
 	  ++had_error;
 	  continue;
@@ -892,15 +888,14 @@  getanswer_r (struct resolv_context *ctx,
 
 	  n = __ns_name_unpack (answer->buf, end_of_message, cp,
 				packtmp, sizeof packtmp);
-	  if (n != -1 && __ns_name_ntop (packtmp, bp, linebuflen) == -1)
+	  if (n < 0)
 	    {
-	      if (__glibc_unlikely (errno == EMSGSIZE))
-		goto too_small;
-
-	      n = -1;
+	      ++had_error;
+	      break;
 	    }
-
-	  if (__glibc_unlikely (n < 0 || res_hnok (bp) == 0))
+	  if (__ns_name_ntop (packtmp, bp, linebuflen) < 0)
+	    goto too_small;
+	  if (__glibc_unlikely (res_hnok (bp) == 0))
 	    {
 	      ++had_error;
 	      break;
@@ -1032,27 +1027,22 @@  gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname,
   u_char packtmp[NS_MAXCDNAME];
   int n = __ns_name_unpack (answer->buf, end_of_message, cp,
 			    packtmp, sizeof packtmp);
+  if (__glibc_unlikely (n < 0))
+    {
+      *errnop = errno;
+      *h_errnop = NO_RECOVERY;
+      return NSS_STATUS_UNAVAIL;
+    }
   /* We unpack the name to check it for validity.  But we do not need
      it later.  */
-  if (n != -1 && __ns_name_ntop (packtmp, buffer, buflen) == -1)
+  if (__ns_name_ntop (packtmp, buffer, buflen) < 0)
     {
-      if (__glibc_unlikely (errno == EMSGSIZE))
-	{
-	too_small:
-	  *errnop = ERANGE;
-	  *h_errnop = NETDB_INTERNAL;
-	  return NSS_STATUS_TRYAGAIN;
-	}
-
-      n = -1;
+    too_small:
+      *errnop = ERANGE;
+      *h_errnop = NETDB_INTERNAL;
+      return NSS_STATUS_TRYAGAIN;
     }
 
-  if (__glibc_unlikely (n < 0))
-    {
-      *errnop = errno;
-      *h_errnop = NO_RECOVERY;
-      return NSS_STATUS_UNAVAIL;
-    }
   if (__glibc_unlikely (res_hnok (buffer) == 0))
     {
       errno = EBADMSG;
@@ -1078,15 +1068,14 @@  gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname,
     {
       n = __ns_name_unpack (answer->buf, end_of_message, cp,
 			    packtmp, sizeof packtmp);
-      if (n != -1 &&
-	  (h_namelen = __ns_name_ntop (packtmp, buffer, buflen)) == -1)
+      if (n < 0)
 	{
-	  if (__glibc_unlikely (errno == EMSGSIZE))
-	    goto too_small;
-
-	  n = -1;
+	  ++had_error;
+	  continue;
 	}
-      if (__glibc_unlikely (n < 0 || res_hnok (buffer) == 0))
+      if ((h_namelen = __ns_name_ntop (packtmp, buffer, buflen)) < 0)
+	goto too_small;
+      if (__glibc_unlikely (res_hnok (buffer) == 0))
 	{
 	  ++had_error;
 	  continue;