File adns-1.4-CVE-2017-9109.patch of Package adns.15333

From fcf2b4e1faf22accb6184cca595aaee602839868 Mon Sep 17 00:00:00 2001
From: Ian Jackson <ijackson@chiark.greenend.org.uk>
Date: Sat, 10 Dec 2016 23:32:49 +0000
Subject: [PATCH 11/32] SECURITY: Ignore apparent answers before first RR we
 found the first time

This way the second answer scan finds the same RRs at the first.
Otherwise, adns can be confused by interleaving answers for the CNAME
target, with the CNAME itself.

In that case the answer data structure (on the heap) can be overrun.

With this change, we prefer to look only at the answer RRs which come
after the CNAME, which is at least arguably correct.

Found by AFL 2.35b.  CVE-2017-9109.

Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
---
 src/reply.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

Index: adns-1.4/src/reply.c
===================================================================
--- adns-1.4.orig/src/reply.c
+++ adns-1.4/src/reply.c
@@ -35,7 +35,7 @@ void adns__procdgram(adns_state ads, con
   int flg_ra, flg_rd, flg_tc, flg_qr, opcode;
   int rrtype, rrclass, rdlength, rdstart;
   int anstart, nsstart, arstart;
-  int ownermatched, l, nrrs;
+  int ownermatched, l, nrrs, restartfrom;
   unsigned long ttl, soattl;
   const typeinfo *typei;
   adns_query qu, nqu;
@@ -163,6 +163,7 @@ void adns__procdgram(adns_state ads, con
    * If it has any CNAMEs we stuff them in the answer.
    */
   wantedrrs= 0;
+  restartfrom= -1;
   cbyte= anstart;
   for (rri= 0; rri<ancount; rri++) {
     rrstart= cbyte;
@@ -230,6 +231,7 @@ void adns__procdgram(adns_state ads, con
 	 */
       }
     } else if (rrtype == (qu->answer->type & adns_rrt_typemask)) {
+      if (restartfrom==-1) restartfrom= rri;
       wantedrrs++;
     } else {
       adns__debug(ads,serv,qu,"ignoring answer RR"
@@ -332,12 +334,14 @@ void adns__procdgram(adns_state ads, con
   pai.arcount= arcount;
   pai.now= now;
 
+  assert(restartfrom>=0);
   for (rri=0, nrrs=0; rri<ancount; rri++) {
     st= adns__findrr(qu,serv, dgram,dglen,&cbyte,
 		     &rrtype,&rrclass,&ttl, &rdlength,&rdstart,
 		     &ownermatched);
     assert(!st); assert(rrtype != -1);
-    if (rrclass != DNS_CLASS_IN ||
+    if (rri < restartfrom ||
+	rrclass != DNS_CLASS_IN ||
 	rrtype != (qu->answer->type & adns_rrt_typemask) ||
 	!ownermatched)
       continue;
openSUSE Build Service is sponsored by