Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-7-0]: src/external/bsd/dhcp/dist/common Pull up following revisio...



details:   https://anonhg.NetBSD.org/src/rev/2fbfe26751ee
branches:  netbsd-7-0
changeset: 801237:2fbfe26751ee
user:      bouyer <bouyer%NetBSD.org@localhost>
date:      Wed Nov 16 08:36:30 2016 +0000

description:
Pull up following revision(s) (requested by snj in ticket #1273):
        external/bsd/dhcp/dist/common/packet.c: revision 1.2
Check correctly the packet length (CVE-2015-8605)

diffstat:

 external/bsd/dhcp/dist/common/packet.c |  56 +++++++++++++++++++++++----------
 1 files changed, 38 insertions(+), 18 deletions(-)

diffs (114 lines):

diff -r 0d84c1b2adbf -r 2fbfe26751ee external/bsd/dhcp/dist/common/packet.c
--- a/external/bsd/dhcp/dist/common/packet.c    Sun Nov 13 07:12:40 2016 +0000
+++ b/external/bsd/dhcp/dist/common/packet.c    Wed Nov 16 08:36:30 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: packet.c,v 1.1.1.4 2014/07/12 11:57:46 spz Exp $       */
+/*     $NetBSD: packet.c,v 1.1.1.4.4.1 2016/11/16 08:36:30 bouyer Exp $        */
 /* packet.c
 
    Packet assembly code, originally contributed by Archie Cobbs. */
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: packet.c,v 1.1.1.4 2014/07/12 11:57:46 spz Exp $");
+__RCSID("$NetBSD: packet.c,v 1.1.1.4.4.1 2016/11/16 08:36:30 bouyer Exp $");
 
 #include "dhcpd.h"
 
@@ -224,7 +224,28 @@
        }
 }
 
-/* UDP header and IP header decoded together for convenience. */
+/*!
+ *
+ * \brief UDP header and IP header decoded together for convenience.
+ *
+ * Attempt to decode the UDP and IP headers and, if necessary, checksum
+ * the packet.
+ *
+ * \param inteface - the interface on which the packet was recevied
+ * \param buf - a pointer to the buffer for the received packet
+ * \param bufix - where to start processing the buffer, previous
+ *                routines may have processed parts of the buffer already
+ * \param from - space to return the address of the packet sender
+ * \param buflen - remaining length of the buffer, this will have been
+ *                 decremented by bufix by the caller
+ * \param rbuflen - space to return the length of the payload from the udp
+ *                  header
+ * \param csum_ready - indication if the checksum is valid for use
+ *                     non-zero indicates the checksum should be validated
+ *
+ * \return - the index to the first byte of the udp payload (that is the
+ *           start of the DHCP packet
+ */
 
 ssize_t
 decode_udp_ip_header(struct interface_info *interface,
@@ -235,7 +256,7 @@
   unsigned char *data;
   struct ip ip;
   struct udphdr udp;
-  unsigned char *upp, *endbuf;
+  unsigned char *upp;
   u_int32_t ip_len, ulen, pkt_len;
   u_int32_t sum, usum;
   static int ip_packets_seen;
@@ -246,11 +267,8 @@
   static int udp_packets_length_overflow;
   unsigned len;
 
-  /* Designate the end of the input buffer for bounds checks. */
-  endbuf = buf + bufix + buflen;
-
   /* Assure there is at least an IP header there. */
-  if ((buf + bufix + sizeof(ip)) > endbuf)
+  if (sizeof(ip) > buflen)
          return -1;
 
   /* Copy the IP header into a stack aligned structure for inspection.
@@ -262,13 +280,17 @@
   ip_len = (*upp & 0x0f) << 2;
   upp += ip_len;
 
-  /* Check the IP packet length. */
+  /* Check packet lengths are within the buffer:
+   * first the ip header (ip_len)
+   * then the packet length from the ip header (pkt_len)
+   * then the udp header (ip_len + sizeof(udp)
+   * We are liberal in what we accept, the udp payload should fit within
+   * pkt_len, but we only check against the full buffer size.
+   */
   pkt_len = ntohs(ip.ip_len);
-  if (pkt_len > buflen)
-       return -1;
-
-  /* Assure after ip_len bytes that there is enough room for a UDP header. */
-  if ((upp + sizeof(udp)) > endbuf)
+  if ((ip_len > buflen) ||
+      (pkt_len > buflen) ||
+      ((ip_len + sizeof(udp)) > buflen))
          return -1;
 
   /* Copy the UDP header into a stack aligned structure for inspection. */
@@ -289,7 +311,8 @@
        return -1;
 
   udp_packets_length_checked++;
-  if ((upp + ulen) > endbuf) {
+  /* verify that the payload length from the udp packet fits in the buffer */
+  if ((ip_len + ulen) > buflen) {
        udp_packets_length_overflow++;
        if ((udp_packets_length_checked > 4) &&
            ((udp_packets_length_checked /
@@ -303,9 +326,6 @@
        return -1;
   }
 
-  if ((ulen < sizeof(udp)) || ((upp + ulen) > endbuf))
-       return -1;
-
   /* Check the IP header checksum - it should be zero. */
   ++ip_packets_seen;
   if (wrapsum (checksum (buf + bufix, ip_len, 0))) {



Home | Main Index | Thread Index | Old Index