diff --git a/sys/netinet6/ip6.h b/sys/netinet6/ip6.h index af9ff05f39b2..550454669c6f 100644 --- a/sys/netinet6/ip6.h +++ b/sys/netinet6/ip6.h @@ -1,4 +1,4 @@ -/* $NetBSD: ip6.h,v 1.4 1999/07/06 12:23:22 itojun Exp $ */ +/* $NetBSD: ip6.h,v 1.5 1999/10/01 10:15:16 itojun Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -214,27 +214,34 @@ struct ip6_frag { */ #define IP6_EXTHDR_CHECK(m, off, hlen, ret) \ -if ((m)->m_next != NULL) { \ +do { \ + if ((m)->m_next != NULL) { \ if (((m)->m_flags & M_LOOP) && \ ((m)->m_len < (off) + (hlen)) && \ (((m) = m_pullup((m), (off) + (hlen))) == NULL)) { \ ip6stat.ip6s_exthdrtoolong++; \ return ret; \ } else if ((m)->m_flags & M_EXT) { \ - if ((m)->m_data + (off) + (hlen) \ - > (caddr_t)(m)->m_ext.ext_buf + MCLBYTES) { \ + if ((m)->m_len < (off) + (hlen)) { \ ip6stat.ip6s_exthdrtoolong++; \ m_freem(m); \ return ret; \ } \ } else { \ - if ((m)->m_data + (off) + (hlen) \ - > (caddr_t)(m) + MSIZE) { \ + if ((m)->m_len < (off) + (hlen)) { \ ip6stat.ip6s_exthdrtoolong++; \ m_freem(m); \ return ret; \ } \ } \ -} + } \ + else { \ + if ((m)->m_len < (off) + (hlen)) { \ + ip6stat.ip6s_toosmall++; \ + m_freem(m); \ + return ret; \ + } \ + } \ +} while (0) #endif /* not _NETINET_IPV6_H_ */ diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c index 7e0992b95604..ace4a02aae9b 100644 --- a/sys/netinet6/ip6_input.c +++ b/sys/netinet6/ip6_input.c @@ -1,4 +1,4 @@ -/* $NetBSD: ip6_input.c,v 1.7 1999/08/07 12:33:04 itojun Exp $ */ +/* $NetBSD: ip6_input.c,v 1.8 1999/10/01 10:15:16 itojun Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -512,6 +512,16 @@ ip6_input(m) ip6stat.ip6s_toomanyhdr++; goto bad; } + + /* + * protection against faulty packet - there should be + * more sanity checks in header chain processing. + */ + if (m->m_pkthdr.len < off) { + ip6stat.ip6s_tooshort++; + goto bad; + } + nxt = (*inet6sw[ip6_protox[nxt]].pr_input)(&m, &off, nxt); } return; @@ -587,6 +597,7 @@ ip6_process_hopopts(m, opthead, hbhlen, rtalertp, plenp) optlen = *(opt + 1) + 2; break; case IP6OPT_RTALERT: + /* XXX may need check for alignment */ if (hbhlen < IP6OPT_RTALERT_LEN) { ip6stat.ip6s_toosmall++; goto bad; @@ -600,6 +611,7 @@ ip6_process_hopopts(m, opthead, hbhlen, rtalertp, plenp) *rtalertp = ntohs(rtalert_val); break; case IP6OPT_JUMBO: + /* XXX may need check for alignment */ if (hbhlen < IP6OPT_JUMBO_LEN) { ip6stat.ip6s_toosmall++; goto bad; @@ -615,7 +627,12 @@ ip6_process_hopopts(m, opthead, hbhlen, rtalertp, plenp) * We can simply cast because of the alignment * requirement of the jumbo payload option. */ +#if 0 *plenp = ntohl(*(u_int32_t *)(opt + 2)); +#else + bcopy(opt + 2, plenp, sizeof(*plenp)); + *plenp = htonl(*plenp); +#endif if (*plenp <= IPV6_MAXPACKET) { /* * jumbo payload length must be larger