chiark / gitweb /
SECURITY: Do not hang, eating CPU, if we encounter a compression pointer loop
[adns.git] / src / parse.c
index 80b79741bc1dbe8d731d9d2fdac8e10352dbb391..790c8ce51b3da32f1f3282d27123d4391022c481 100644 (file)
@@ -4,7 +4,7 @@
  */
 /*
  *  This file is part of adns, which is
- *    Copyright (C) 1997-2000,2003,2006,2014  Ian Jackson
+ *    Copyright (C) 1997-2000,2003,2006,2014-2016  Ian Jackson
  *    Copyright (C) 2014  Mark Wooding
  *    Copyright (C) 1999-2000,2003,2006  Tony Finch
  *    Copyright (C) 1991 Massachusetts Institute of Technology
@@ -26,7 +26,7 @@
 
 #include "internal.h"
 
-int vbuf__append_quoted1035(vbuf *vb, const byte *buf, int len) {
+static int vbuf_append_quoted1035(vbuf *vb, const byte *buf, int len) {
   char qbuf[10];
   int i, ch;
   
@@ -71,6 +71,7 @@ adns_status adns__findlabel_next(findlabel_state *fls,
                                 int *lablen_r, int *labstart_r) {
   int lablen, jumpto;
   const char *dgram;
+  int had_pointer= 0;
 
   dgram= fls->dgram;
   for (;;) {
@@ -81,6 +82,7 @@ adns_status adns__findlabel_next(findlabel_state *fls,
     if ((lablen & 0x0c0) != 0x0c0) return adns_s_unknownformat;
     if (fls->cbyte >= fls->dglen) goto x_truncated;
     if (fls->cbyte >= fls->max) goto x_badresponse;
+    if (had_pointer++ >= 2) goto x_loop;
     GET_B(fls->cbyte,jumpto);
     jumpto |= (lablen&0x3f)<<8;
     if (fls->dmend_r) *(fls->dmend_r)= fls->cbyte;
@@ -109,6 +111,11 @@ adns_status adns__findlabel_next(findlabel_state *fls,
   adns__diag(fls->ads,fls->serv,fls->qu,
             "label in domain runs beyond end of domain");
   return adns_s_invalidresponse;
+
+ x_loop: 
+  adns__diag(fls->ads,fls->serv,fls->qu,
+            "compressed label pointer chain");
+  return adns_s_invalidresponse;
 }
 
 adns_status adns__parse_domain(adns_state ads, int serv, adns_query qu,
@@ -142,7 +149,7 @@ adns_status adns__parse_domain_more(findlabel_state *fls, adns_state ads,
       if (!adns__vbuf_append(vb,".",1)) return adns_s_nomemory;
     }
     if (flags & pdf_quoteok) {
-      if (!vbuf__append_quoted1035(vb,dgram+labstart,lablen))
+      if (!vbuf_append_quoted1035(vb,dgram+labstart,lablen))
        return adns_s_nomemory;
     } else {
       ch= dgram[labstart];