From: Paul Mackerras Date: Fri, 24 May 1996 07:04:55 +0000 (+0000) Subject: check that VJ-unc header doesn't overflow buffer X-Git-Tag: RELEASE_2_3_6~476 X-Git-Url: http://git.ozlabs.org/?p=ppp.git;a=commitdiff_plain;h=31e80dd05aec83cbee14a9ede031023188e31270 check that VJ-unc header doesn't overflow buffer --- diff --git a/NeXT/vjcompress.c b/NeXT/vjcompress.c index 237b1ff..0a0a29a 100644 --- a/NeXT/vjcompress.c +++ b/NeXT/vjcompress.c @@ -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 @@ -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); diff --git a/freebsd-2.0/pppcompress.c b/freebsd-2.0/pppcompress.c index 9967eb7..383ca58 100644 --- a/freebsd-2.0/pppcompress.c +++ b/freebsd-2.0/pppcompress.c @@ -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 @@ -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) diff --git a/modules/vjcompress.c b/modules/vjcompress.c index 2507573..eecbef5 100644 --- a/modules/vjcompress.c +++ b/modules/vjcompress.c @@ -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 @@ -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); diff --git a/netbsd-1.1/slcompress.c b/netbsd-1.1/slcompress.c index 7a0e24e..c46c57f 100644 --- a/netbsd-1.1/slcompress.c +++ b/netbsd-1.1/slcompress.c @@ -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) diff --git a/ultrix/slcompress.c b/ultrix/slcompress.c index ecbdf3b..1cbdd3f 100644 --- a/ultrix/slcompress.c +++ b/ultrix/slcompress.c @@ -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)