nss_dns: Enforce QDCOUNT == 1 in getnetby* implementation

Message ID 20190308204449.3567B80DD6B5@oldenburg2.str.redhat.com
State New, archived
Headers

Commit Message

Florian Weimer March 8, 2019, 8:44 p.m. UTC
  The stub resolver sends a query with one question record, so if
the answer contains a different number, the DNS message is
corrupted.

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

	* resolv/nss_dns/dns-network.c (getanswer_r): Bail out if question
	count is not one.
  

Patch

diff --git a/resolv/nss_dns/dns-network.c b/resolv/nss_dns/dns-network.c
index 4617b165db..9c0082d270 100644
--- a/resolv/nss_dns/dns-network.c
+++ b/resolv/nss_dns/dns-network.c
@@ -300,34 +300,21 @@  getanswer_r (const querybuf *answer, int anslen, struct netent *result,
   int have_answer;
   u_char packtmp[NS_MAXCDNAME];
 
-  if (question_count == 0)
+  if (question_count != 1)
     {
-      /* FIXME: the Sun version uses for host name lookup an additional
-	 parameter for pointing to h_errno.  this is missing here.
-	 OSF/1 has a per-thread h_errno variable.  */
-      if (header_pointer->aa != 0)
-	{
-	  __set_h_errno (HOST_NOT_FOUND);
-	  return NSS_STATUS_NOTFOUND;
-	}
-      else
-	{
-	  __set_h_errno (TRY_AGAIN);
-	  return NSS_STATUS_TRYAGAIN;
-	}
+    bad_message:
+      *errnop = EBADMSG;
+      __set_h_errno (NO_RECOVERY);
+      return NSS_STATUS_UNAVAIL;
     }
 
   /* Skip the question part.  */
-  while (question_count-- > 0)
-    {
-      int n = __dn_skipname (cp, end_of_message);
-      if (n < 0 || end_of_message - (cp + n) < QFIXEDSZ)
-       {
-         __set_h_errno (NO_RECOVERY);
-         return NSS_STATUS_UNAVAIL;
-       }
-      cp += n + QFIXEDSZ;
-    }
+  {
+    int n = __dn_skipname (cp, end_of_message);
+    if (n < 0 || end_of_message - (cp + n) < QFIXEDSZ)
+      goto bad_message;
+    cp += n + QFIXEDSZ;
+  }
 
   alias_pointer = result->n_aliases = &net_data->aliases[0];
   *alias_pointer = NULL;