Make ip_len and ip_off unsigned values; don't transmit or accept packets
authortholo <tholo@openbsd.org>
Sun, 26 Jan 1997 01:23:42 +0000 (01:23 +0000)
committertholo <tholo@openbsd.org>
Sun, 26 Jan 1997 01:23:42 +0000 (01:23 +0000)
larger than the maximum IP packet size.  From NetBSD.

sys/netinet/ip.h
sys/netinet/ip_input.c
sys/netinet/ip_var.h
sys/netinet/raw_ip.c
sys/netinet/udp.h
sys/netinet/udp_usrreq.c

index 3214fb3..fb86631 100644 (file)
 
 /*
  * Structure of an internet header, naked of options.
- *
- * We declare ip_len and ip_off to be short, rather than u_short
- * pragmatically since otherwise unsigned comparisons can result
- * against negative integers quite easily, and fail in subtle ways.
  */
 struct ip {
 #if BYTE_ORDER == LITTLE_ENDIAN
@@ -58,9 +54,9 @@ struct ip {
                  ip_hl:4;              /* header length */
 #endif
        u_int8_t  ip_tos;               /* type of service */
-       int16_t   ip_len;               /* total length */
+       u_int16_t ip_len;               /* total length */
        u_int16_t ip_id;                /* identification */
-       int16_t   ip_off;               /* fragment offset field */
+       u_int16_t ip_off;               /* fragment offset field */
 #define        IP_RF 0x8000                    /* reserved fragment flag */
 #define        IP_DF 0x4000                    /* dont fragment flag */
 #define        IP_MF 0x2000                    /* more fragments flag */
index 89b2beb..2d8ab0b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ip_input.c,v 1.19 1996/10/27 00:47:33 deraadt Exp $   */
+/*     $OpenBSD: ip_input.c,v 1.20 1997/01/26 01:23:43 tholo Exp $     */
 /*     $NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $   */
 
 /*
@@ -569,10 +569,16 @@ insert:
                return (0);
 
        /*
-        * Reassembly is complete; concatenate fragments.
+        * Reassembly is complete.  Check for a bogus message size and
+        * concatenate fragments.
         */
        q = fp->ipq_fragq.lh_first;
        ip = q->ipqe_ip;
+       if ((next + (ip->ip_hl << 2)) > IP_MAXPACKET) {
+               ipstat.ips_toolong++;
+               ip_freef(fp);
+               return (0);
+       }
        m = dtom(q->ipqe_ip);
        t = m->m_next;
        m->m_next = 0;
index 7caed51..c79623b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ip_var.h,v 1.3 1996/03/03 22:30:42 niklas Exp $       */
+/*     $OpenBSD: ip_var.h,v 1.4 1997/01/26 01:23:44 tholo Exp $        */
 /*     $NetBSD: ip_var.h,v 1.16 1996/02/13 23:43:20 christos Exp $     */
 
 /*
  * Overlay for ip header used by other protocols (tcp, udp).
  */
 struct ipovly {
-       u_int8_t ih_x1[9];              /* (unused) */
-       u_int8_t ih_pr;                 /* protocol */
-       int16_t  ih_len;                /* protocol length */
-       struct   in_addr ih_src;        /* source internet address */
-       struct   in_addr ih_dst;        /* destination internet address */
+       u_int8_t  ih_x1[9];             /* (unused) */
+       u_int8_t  ih_pr;                /* protocol */
+       u_int16_t ih_len;               /* protocol length */
+       struct    in_addr ih_src;       /* source internet address */
+       struct    in_addr ih_dst;       /* destination internet address */
 };
 
 /*
@@ -144,6 +144,7 @@ struct      ipstat {
        u_long  ips_rawout;             /* total raw ip packets generated */
        u_long  ips_badfrags;           /* malformed fragments (bad length) */
        u_long  ips_rcvmemdrop;         /* frags dropped for lack of memory */
+       u_long  ips_toolong;            /* ip length > max ip packet size */
 };
 
 #ifdef _KERNEL
index aaedb61..97d641f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: raw_ip.c,v 1.7 1996/08/14 20:19:20 deraadt Exp $      */
+/*     $OpenBSD: raw_ip.c,v 1.8 1997/01/26 01:23:44 tholo Exp $        */
 /*     $NetBSD: raw_ip.c,v 1.25 1996/02/18 18:58:33 christos Exp $     */
 
 /*
@@ -171,6 +171,10 @@ rip_output(m, va_alist)
         * Otherwise, allocate an mbuf for a header and fill it in.
         */
        if ((inp->inp_flags & INP_HDRINCL) == 0) {
+               if ((m->m_pkthdr.len + sizeof(struct ip)) > IP_MAXPACKET) {
+                       m_freem(m);
+                       return (EMSGSIZE);
+               }
                M_PREPEND(m, sizeof(struct ip), M_WAIT);
                ip = mtod(m, struct ip *);
                ip->ip_tos = 0;
@@ -181,6 +185,10 @@ rip_output(m, va_alist)
                ip->ip_dst.s_addr = dst;
                ip->ip_ttl = MAXTTL;
        } else {
+               if (m->m_pkthdr.len > IP_MAXPACKET) {
+                       m_freem(m);
+                       return (EMSGSIZE);
+               }
                ip = mtod(m, struct ip *);
                /*
                 * don't allow both user specified and setsockopt options,
index c7964df..95bc044 100644 (file)
@@ -42,6 +42,6 @@
 struct udphdr {
        u_int16_t uh_sport;             /* source port */
        u_int16_t uh_dport;             /* destination port */
-       int16_t   uh_ulen;              /* udp length */
+       u_int16_t uh_ulen;              /* udp length */
        u_int16_t uh_sum;               /* udp checksum */
 };
index f78e4be..31bdf85 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: udp_usrreq.c,v 1.7 1996/07/05 20:42:18 deraadt Exp $  */
+/*     $OpenBSD: udp_usrreq.c,v 1.8 1997/01/26 01:23:46 tholo Exp $    */
 /*     $NetBSD: udp_usrreq.c,v 1.28 1996/03/16 23:54:03 christos Exp $ */
 
 /*
@@ -460,6 +460,15 @@ udp_output(m, va_alist)
                goto bail;
        }
 
+       /*
+        * Compute the packet length of the IP header, and
+        * punt if the length looks bogus.
+        */
+       if ((len + sizeof(struct udpiphdr)) > IP_MAXPACKET) {
+               error = EMSGSIZE;
+               goto release;
+       }
+
        /*
         * Fill in mbuf with extended UDP header
         * and addresses and length put into network format.