]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
DW:
authorwessels <>
Sat, 4 Nov 2000 00:03:54 +0000 (00:03 +0000)
committerwessels <>
Sat, 4 Nov 2000 00:03:54 +0000 (00:03 +0000)
 - A fix for problems relating to large DNS replies.  RFC 1035 says
   that DNS/UDP messages must be 512 octets or less.  Some servers
   (BIND on OS/2) are sending larger packets, but Squid was only
   reading the first 512 octets.  This could cause buffer overruns
   in rfc1035.c.

   This patch changes recv() to use the maximum UDP socket buffer
   size.  However, if we get a large reply we tell rfc1035.c that
   we only got 512 octets.  Thus, its a little safer if that code
   has bugs and reads past 512.

src/dns_internal.cc

index b5fee99b22ef812efdc552c6ba2dfe2a92a234c8..1496bdb099e896b627d66abf377d5e5f80fa62de 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: dns_internal.cc,v 1.33 2000/11/02 16:30:10 wessels Exp $
+ * $Id: dns_internal.cc,v 1.34 2000/11/03 17:03:54 wessels Exp $
  *
  * DEBUG: section 78    DNS lookups; interacts with lib/rfc1035.c
  * AUTHOR: Duane Wessels
@@ -67,6 +67,7 @@ struct _ns {
     struct sockaddr_in S;
     int nqueries;
     int nreplies;
+    int large_pkts;
 };
 
 static ns *nameservers = NULL;
@@ -334,7 +335,7 @@ idnsRead(int fd, void *data)
     struct sockaddr_in from;
     socklen_t from_len;
     int max = INCOMING_DNS_MAX;
-    static char rbuf[512];
+    static char rbuf[SQUID_UDP_SO_RCVBUF];
     int ns;
     while (max--) {
        from_len = sizeof(from);
@@ -376,6 +377,23 @@ idnsRead(int fd, void *data)
            }
            continue;
        }
+       if (len > 512) {
+           /*
+            * Check for non-conforming replies.  RFC 1035 says
+            * DNS/UDP messages must be 512 octets or less.  If we
+            * get one that is too large, we generate a warning
+            * and then pretend that we only got 512 octets.  This
+            * should prevent the rfc1035.c code from reading past
+            * the end of our buffer.
+            */
+           static int other_large_pkts = 0;
+           int x;
+           x = (ns < 0) ? ++other_large_pkts : ++nameservers[ns].large_pkts;
+           if (isPowTen(x))
+               debug(78, 1) ("WARNING: Got %d large DNS replies from %s\n",
+                   x, inet_ntoa(from.sin_addr));
+           len = 512;
+       }
        idnsGrokReply(rbuf, len);
     }
     if (lru_list.head)