--- a/sys/net/ppp_layer/slcompress.c +++ b/sys/net/ppp_layer/slcompress.c @@ -113,7 +113,9 @@ } #define DECODEL(f) { \ + if (cp + 1 > buf + buflen) goto bad; \ if (*cp == 0) {\ + if (cp + 3 > buf + buflen) goto bad; \ (f) = htonl(ntohl(f) + ((cp[1] << 8) | cp[2])); \ cp += 3; \ } else { \ @@ -122,7 +124,9 @@ } #define DECODES(f) { \ + if (cp + 1 > buf + buflen) goto bad; \ if (*cp == 0) {\ + if (cp + 3 > buf + buflen) goto bad; \ (f) = htons(ntohs(f) + ((cp[1] << 8) | cp[2])); \ cp += 3; \ } else { \ @@ -131,7 +135,9 @@ } #define DECODEU(f) { \ + if (cp + 1 > buf + buflen) goto bad; \ if (*cp == 0) {\ + if (cp + 3 > buf + buflen) goto bad; \ (f) = htons((cp[1] << 8) | cp[2]); \ cp += 3; \ } else { \ @@ -465,10 +471,14 @@ u_int16_t *bp; u_int vjlen; + if (buflen < 1) /* need the type/dispatch byte */ + goto bad; switch (type) { case TYPE_UNCOMPRESSED_TCP: ip = (struct ip *) buf; + if (buflen < (int)sizeof(struct ip)) + goto bad; if (ip->ip_p >= MAX_STATES) goto bad; cs = &comp->rstate[comp->last_recv = ip->ip_p]; @@ -500,8 +510,12 @@ /* We've got a compressed packet. */ INCR(sls_compressedin) cp = buf; + if (cp + 1 > buf + buflen) /* changes byte */ + goto bad; changes = *cp++; if (changes & NEW_C) { + if (cp + 1 > buf + buflen) /* connection id byte */ + goto bad; /* Make sure the state index is in range, then grab the state. * If we have a good state index, clear the 'discard' flag. */ if (*cp >= MAX_STATES) @@ -518,6 +532,8 @@ return (-1); } } + if (cp + 2 > buf + buflen) /* tcp checksum (2 bytes) */ + goto bad; cs = &comp->rstate[comp->last_recv]; hlen = cs->cs_ip.ip_hl << 2; th = (struct tcphdr *)&((u_char *)&cs->cs_ip)[hlen];