nss_dns: Skip over non-PTR records in the netent code [BZ #19868]
authorFlorian Weimer <fweimer@redhat.com>
Wed, 27 Apr 2016 15:15:57 +0000 (17:15 +0200)
committerFlorian Weimer <fweimer@redhat.com>
Wed, 27 Apr 2016 15:15:57 +0000 (17:15 +0200)
This requires additional checks for the RDATA length and the
availability of record metadata.

ChangeLog
resolv/nss_dns/dns-network.c

index 4c8d7bc..91061fb 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2016-03-25  Florian Weimer  <fweimer@redhat.com>
+
+       [BZ #19868]
+       * resolv/nss_dns/dns-network.c (getanswer_r): Implement additional
+       DNS packet syntax checks (which were not needed before).  Skip
+       over non-PTR records.
+
 2016-04-27  Florian Weimer  <fweimer@redhat.com>
 
        * resolv/nss_dns/dns-network.c (offsetof): Remove macro
index 99ec755..3ae25c7 100644 (file)
@@ -343,10 +343,23 @@ getanswer_r (const querybuf *answer, int anslen, struct netent *result,
       if (n < 0 || res_dnok (bp) == 0)
        break;
       cp += n;
+
+      if (end_of_message - cp < 10)
+       {
+         __set_h_errno (NO_RECOVERY);
+         return NSS_STATUS_UNAVAIL;
+       }
+
       GETSHORT (type, cp);
       GETSHORT (class, cp);
       cp += INT32SZ;           /* TTL */
-      GETSHORT (n, cp);
+      uint16_t rdatalen;
+      GETSHORT (rdatalen, cp);
+      if (end_of_message - cp < rdatalen)
+       {
+         __set_h_errno (NO_RECOVERY);
+         return NSS_STATUS_UNAVAIL;
+       }
 
       if (class == C_IN && type == T_PTR)
        {
@@ -368,7 +381,7 @@ getanswer_r (const querybuf *answer, int anslen, struct netent *result,
              cp += n;
              return NSS_STATUS_UNAVAIL;
            }
-         cp += n;
+         cp += rdatalen;
          if (alias_pointer + 2 < &net_data->aliases[MAX_NR_ALIASES])
            {
              *alias_pointer++ = bp;
@@ -379,6 +392,9 @@ getanswer_r (const querybuf *answer, int anslen, struct netent *result,
              ++have_answer;
            }
        }
+      else
+       /* Skip over unknown record data.  */
+       cp += rdatalen;
     }
 
   if (have_answer)