check that VJ-unc header doesn't overflow buffer
authorPaul Mackerras <paulus@samba.org>
Fri, 24 May 1996 07:04:55 +0000 (07:04 +0000)
committerPaul Mackerras <paulus@samba.org>
Fri, 24 May 1996 07:04:55 +0000 (07:04 +0000)
NeXT/vjcompress.c
freebsd-2.0/pppcompress.c
modules/vjcompress.c
netbsd-1.1/slcompress.c
ultrix/slcompress.c

index 237b1ff78958717a1998c389c1bb95fa1acabd6b..0a0a29a3929dabd9a2a963c0b70d4c6e55b5a6d1 100644 (file)
@@ -29,7 +29,7 @@
  * This version is used under SunOS 4.x, DEC Alpha OSF/1, AIX 4.x,
  * and SVR4 systems including Solaris 2.
  *
- * $Id: vjcompress.c,v 1.1 1995/12/18 03:30:20 paulus Exp $
+ * $Id: vjcompress.c,v 1.2 1996/05/24 07:04:06 paulus Exp $
  */
 
 #include <sys/types.h>
@@ -439,7 +439,12 @@ vj_uncompress_uncomp(buf, comp)
     register struct ip *ip;
 
     ip = (struct ip *) buf;
-    if (ip->ip_p >= MAX_STATES) {
+    hlen = getip_hl(*ip) << 2;
+    if (ip->ip_p >= MAX_STATES
+       || hlen + sizeof(struct tcphdr) > buflen
+       || (hlen += getth_off(*((struct tcphdr *)&((char *)ip)[hlen])) << 2)
+           > buflen
+       || hlen > MAX_HDR) {
        comp->flags |= VJF_TOSS;
        INCR(vjs_errorin);
        return (0);
@@ -447,9 +452,6 @@ vj_uncompress_uncomp(buf, comp)
     cs = &comp->rstate[comp->last_recv = ip->ip_p];
     comp->flags &=~ VJF_TOSS;
     ip->ip_p = IPPROTO_TCP;
-    hlen = getip_hl(*ip);
-    hlen += getth_off(*((struct tcphdr *)&((int *)ip)[hlen]));
-    hlen <<= 2;
     BCOPY(ip, &cs->cs_ip, hlen);
     cs->cs_hlen = hlen;
     INCR(vjs_uncompressedin);
index 9967eb784e59484d13b36ae6c45f98813d57f755..383ca5854aa66b13b5b13d2547b4d22dc4a25d71 100644 (file)
@@ -40,7 +40,7 @@
  * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989:
  *    - Initial distribution.
  *
- *     $Id: pppcompress.c,v 1.1 1994/12/15 22:27:17 paulus Exp $
+ *     $Id: pppcompress.c,v 1.2 1996/05/24 07:04:14 paulus Exp $
  */
   
 #include <sys/types.h>
@@ -471,9 +471,16 @@ vj_uncompress_tcp_core(buf, buflen, total_len, type, comp, hdrp, hlenp)
                cs = &comp->rstate[comp->last_recv = ip->ip_p];
                comp->flags &=~ SLF_TOSS;
                ip->ip_p = IPPROTO_TCP;
-               hlen = ip->ip_hl;
-               hlen += ((struct tcphdr *)&((int *)ip)[hlen])->th_off;
-               hlen <<= 2;
+               /*
+                * Calculate the size of the TCP/IP header and make sure that
+                * we don't overflow the space we have available for it.
+                */
+               hlen = ip->ip_hl << 2;
+               if (hlen + sizeof(struct tcphdr) > buflen)
+                       goto bad;
+               hlen += ((struct tcphdr *)&((char *)ip)[hlen])->th_off << 2;
+               if (hlen > MAX_HDR || hlen > buflen)
+                       goto bad;
                BCOPY(ip, &cs->cs_ip, hlen);
                cs->cs_hlen = hlen;
                INCR(sls_uncompressedin)
index 2507573eedbfe215e1e7b50738147957d8cc3043..eecbef5b35868589936692ce02783d0ac7da2546 100644 (file)
@@ -29,7 +29,7 @@
  * This version is used under SunOS 4.x, DEC Alpha OSF/1, AIX 4.x,
  * and SVR4 systems including Solaris 2.
  *
- * $Id: vjcompress.c,v 1.7 1995/12/11 02:57:49 paulus Exp $
+ * $Id: vjcompress.c,v 1.8 1996/05/24 07:04:26 paulus Exp $
  */
 
 #include <sys/types.h>
@@ -430,8 +430,9 @@ vj_uncompress_err(comp)
  * "Uncompress" a packet of type TYPE_UNCOMPRESSED_TCP.
  */
 int
-vj_uncompress_uncomp(buf, comp)
+vj_uncompress_uncomp(buf, buflen, comp)
     u_char *buf;
+    int buflen;
     struct vjcompress *comp;
 {
     register u_int hlen;
@@ -439,7 +440,12 @@ vj_uncompress_uncomp(buf, comp)
     register struct ip *ip;
 
     ip = (struct ip *) buf;
-    if (ip->ip_p >= MAX_STATES) {
+    hlen = getip_hl(*ip) << 2;
+    if (ip->ip_p >= MAX_STATES
+       || hlen + sizeof(struct tcphdr) > buflen
+       || (hlen += getth_off(*((struct tcphdr *)&((char *)ip)[hlen])) << 2)
+           > buflen
+       || hlen > MAX_HDR) {
        comp->flags |= VJF_TOSS;
        INCR(vjs_errorin);
        return (0);
@@ -447,9 +453,6 @@ vj_uncompress_uncomp(buf, comp)
     cs = &comp->rstate[comp->last_recv = ip->ip_p];
     comp->flags &=~ VJF_TOSS;
     ip->ip_p = IPPROTO_TCP;
-    hlen = getip_hl(*ip);
-    hlen += getth_off(*((struct tcphdr *)&((int *)ip)[hlen]));
-    hlen <<= 2;
     BCOPY(ip, &cs->cs_ip, hlen);
     cs->cs_hlen = hlen;
     INCR(vjs_uncompressedin);
index 7a0e24e43408f0df52c24f808bcf410824627abb..c46c57f7f14a075a99f5cc9fe6326535ca4fbce2 100644 (file)
@@ -1,4 +1,4 @@
-/*     $Id: slcompress.c,v 1.2 1996/04/04 04:17:44 paulus Exp $        */
+/*     $Id: slcompress.c,v 1.3 1996/05/24 07:04:47 paulus Exp $        */
 
 /*
  * Copyright (c) 1989, 1993, 1994
@@ -477,9 +477,16 @@ sl_uncompress_tcp_core(buf, buflen, total_len, type, comp, hdrp, hlenp)
                cs = &comp->rstate[comp->last_recv = ip->ip_p];
                comp->flags &=~ SLF_TOSS;
                ip->ip_p = IPPROTO_TCP;
-               hlen = ip->ip_hl;
-               hlen += ((struct tcphdr *)&((int32_t *)ip)[hlen])->th_off;
-               hlen <<= 2;
+               /*
+                * Calculate the size of the TCP/IP header and make sure that
+                * we don't overflow the space we have available for it.
+                */
+               hlen = ip->ip_hl << 2;
+               if (hlen + sizeof(struct tcphdr) > buflen)
+                       goto bad;
+               hlen += ((struct tcphdr *)&((char *)ip)[hlen])->th_off << 2;
+               if (hlen > MAX_HDR || hlen > buflen)
+                       goto bad;
                BCOPY(ip, &cs->cs_ip, hlen);
                cs->cs_hlen = hlen;
                INCR(sls_uncompressedin)
index ecbdf3b81df80cc35fdea0bd525d62f078942636..1cbdd3f79f7d5c052e523f55534abc2252a9f5cd 100644 (file)
@@ -24,7 +24,7 @@
  * so that the entire packet being decompressed doesn't have
  * to be in contiguous memory (just the compressed header).
  *
- * $Id: slcompress.c,v 1.2 1994/11/28 01:42:00 paulus Exp $
+ * $Id: slcompress.c,v 1.3 1996/05/24 07:04:55 paulus Exp $
  */
 
 #include "../h/types.h"
@@ -482,9 +482,16 @@ sl_uncompress_tcp_core(buf, buflen, total_len, type, comp, hdrp, hlenp)
                cs = &comp->rstate[comp->last_recv = ip->ip_p];
                comp->flags &=~ SLF_TOSS;
                ip->ip_p = IPPROTO_TCP;
-               hlen = ip->ip_hl;
-               hlen += ((struct tcphdr *)&((int *)ip)[hlen])->th_off;
-               hlen <<= 2;
+               /*
+                * Calculate the size of the TCP/IP header and make sure that
+                * we don't overflow the space we have available for it.
+                */
+               hlen = ip->ip_hl << 2;
+               if (hlen + sizeof(struct tcphdr) > buflen)
+                       goto bad;
+               hlen += ((struct tcphdr *)&((char *)ip)[hlen])->th_off << 2;
+               if (hlen > MAX_HDR || hlen > buflen)
+                       goto bad;
                BCOPY(ip, &cs->cs_ip, hlen);
                cs->cs_hlen = hlen;
                INCR(sls_uncompressedin)