aboutsummaryrefslogtreecommitdiff
path: root/sys/netinet6
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netinet6')
-rw-r--r--sys/netinet6/dest6.c24
-rw-r--r--sys/netinet6/frag6.c12
-rw-r--r--sys/netinet6/icmp6.c143
-rw-r--r--sys/netinet6/ip6_input.c24
-rw-r--r--sys/netinet6/ip6_mroute.c10
-rw-r--r--sys/netinet6/mld6.c20
-rw-r--r--sys/netinet6/nd6_nbr.c20
-rw-r--r--sys/netinet6/nd6_rtr.c20
-rw-r--r--sys/netinet6/route6.c12
-rw-r--r--sys/netinet6/sctp6_usrreq.c10
-rw-r--r--sys/netinet6/udp6_usrreq.c12
11 files changed, 183 insertions, 124 deletions
diff --git a/sys/netinet6/dest6.c b/sys/netinet6/dest6.c
index 3ec199138b6c..09b84f589543 100644
--- a/sys/netinet6/dest6.c
+++ b/sys/netinet6/dest6.c
@@ -73,20 +73,24 @@ dest6_input(struct mbuf **mp, int *offp, int proto)
off = *offp;
/* Validation of the length of the header. */
- m = m_pullup(m, off + sizeof(*dstopts));
- if (m == NULL) {
- IP6STAT_INC(ip6s_exthdrtoolong);
- *mp = m;
- return (IPPROTO_DONE);
+ if (m->m_len < off + sizeof(*dstopts)) {
+ m = m_pullup(m, off + sizeof(*dstopts));
+ if (m == NULL) {
+ IP6STAT_INC(ip6s_exthdrtoolong);
+ *mp = m;
+ return (IPPROTO_DONE);
+ }
}
dstopts = (struct ip6_dest *)(mtod(m, caddr_t) + off);
dstoptlen = (dstopts->ip6d_len + 1) << 3;
- m = m_pullup(m, off + dstoptlen);
- if (m == NULL) {
- IP6STAT_INC(ip6s_exthdrtoolong);
- *mp = m;
- return (IPPROTO_DONE);
+ if (m->m_len < off + dstoptlen) {
+ m = m_pullup(m, off + dstoptlen);
+ if (m == NULL) {
+ IP6STAT_INC(ip6s_exthdrtoolong);
+ *mp = m;
+ return (IPPROTO_DONE);
+ }
}
dstopts = (struct ip6_dest *)(mtod(m, caddr_t) + off);
off += dstoptlen;
diff --git a/sys/netinet6/frag6.c b/sys/netinet6/frag6.c
index 25e124adf4d3..15b2c2a14af0 100644
--- a/sys/netinet6/frag6.c
+++ b/sys/netinet6/frag6.c
@@ -389,11 +389,13 @@ frag6_input(struct mbuf **mp, int *offp, int proto)
M_ASSERTPKTHDR(m);
- m = m_pullup(m, offset + sizeof(struct ip6_frag));
- if (m == NULL) {
- IP6STAT_INC(ip6s_exthdrtoolong);
- *mp = NULL;
- return (IPPROTO_DONE);
+ if (m->m_len < offset + sizeof(struct ip6_frag)) {
+ m = m_pullup(m, offset + sizeof(struct ip6_frag));
+ if (m == NULL) {
+ IP6STAT_INC(ip6s_exthdrtoolong);
+ *mp = NULL;
+ return (IPPROTO_DONE);
+ }
}
ip6 = mtod(m, struct ip6_hdr *);
diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c
index 92624bf43042..141da4e658d6 100644
--- a/sys/netinet6/icmp6.c
+++ b/sys/netinet6/icmp6.c
@@ -317,10 +317,12 @@ icmp6_error(struct mbuf *m, int type, int code, int param)
if (off >= 0 && nxt == IPPROTO_ICMPV6) {
struct icmp6_hdr *icp;
- m = m_pullup(m, off + sizeof(struct icmp6_hdr));
- if (m == NULL) {
- IP6STAT_INC(ip6s_exthdrtoolong);
- return;
+ if (m->m_len < off + sizeof(struct icmp6_hdr)) {
+ m = m_pullup(m, off + sizeof(struct icmp6_hdr));
+ if (m == NULL) {
+ IP6STAT_INC(ip6s_exthdrtoolong);
+ return;
+ }
}
oip6 = mtod(m, struct ip6_hdr *);
icp = (struct icmp6_hdr *)(mtod(m, caddr_t) + off);
@@ -401,11 +403,13 @@ icmp6_input(struct mbuf **mp, int *offp, int proto)
m = *mp;
off = *offp;
- m = m_pullup(m, off + sizeof(struct icmp6_hdr));
- if (m == NULL) {
- IP6STAT_INC(ip6s_exthdrtoolong);
- *mp = m;
- return (IPPROTO_DONE);
+ if (m->m_len < off + sizeof(struct icmp6_hdr)) {
+ m = m_pullup(m, off + sizeof(struct icmp6_hdr));
+ if (m == NULL) {
+ IP6STAT_INC(ip6s_exthdrtoolong);
+ *mp = m;
+ return (IPPROTO_DONE);
+ }
}
/*
@@ -566,10 +570,12 @@ icmp6_input(struct mbuf **mp, int *offp, int proto)
n->m_pkthdr.len = n0len + (noff - off);
n->m_next = n0;
} else {
- n = m_pullup(n, off + sizeof(*nicmp6));
- if (n == NULL) {
- IP6STAT_INC(ip6s_exthdrtoolong);
- break;
+ if (n->m_len < off + sizeof(*nicmp6)) {
+ n = m_pullup(n, off + sizeof(*nicmp6));
+ if (n == NULL) {
+ IP6STAT_INC(ip6s_exthdrtoolong);
+ break;
+ }
}
nicmp6 = (struct icmp6_hdr *)(mtod(n, caddr_t) + off);
noff = off;
@@ -635,11 +641,14 @@ icmp6_input(struct mbuf **mp, int *offp, int proto)
if (pr == NULL)
pr = curthread->td_ucred->cr_prison;
if (mode == FQDN) {
- m = m_pullup(m, off + sizeof(struct icmp6_nodeinfo));
- if (m == NULL) {
- IP6STAT_INC(ip6s_exthdrtoolong);
- *mp = m;
- return (IPPROTO_DONE);
+ if (m->m_len < off + sizeof(struct icmp6_nodeinfo)) {
+ m = m_pullup(m, off +
+ sizeof(struct icmp6_nodeinfo));
+ if (m == NULL) {
+ IP6STAT_INC(ip6s_exthdrtoolong);
+ *mp = m;
+ return (IPPROTO_DONE);
+ }
}
n = m_copym(m, 0, M_COPYALL, M_NOWAIT);
if (n)
@@ -725,11 +734,13 @@ icmp6_input(struct mbuf **mp, int *offp, int proto)
if (icmp6len < sizeof(struct nd_router_solicit))
goto badlen;
if (send_sendso_input_hook != NULL) {
- m = m_pullup(m, off + icmp6len);
- if (m == NULL) {
- IP6STAT_INC(ip6s_exthdrtoolong);
- *mp = NULL;
- return (IPPROTO_DONE);
+ if (m->m_len < off + icmp6len) {
+ m = m_pullup(m, off + icmp6len);
+ if (m == NULL) {
+ IP6STAT_INC(ip6s_exthdrtoolong);
+ *mp = NULL;
+ return (IPPROTO_DONE);
+ }
}
error = send_sendso_input_hook(m, ifp, SND_IN, ip6len);
if (error == 0) {
@@ -891,11 +902,13 @@ icmp6_notify_error(struct mbuf **mp, int off, int icmp6len, int code)
goto freeit;
}
- m = m_pullup(m, off + sizeof(*icmp6) + sizeof(struct ip6_hdr));
- if (m == NULL) {
- IP6STAT_INC(ip6s_exthdrtoolong);
- *mp = m;
- return (-1);
+ if (m->m_len < off + sizeof(*icmp6) + sizeof(struct ip6_hdr)) {
+ m = m_pullup(m, off + sizeof(*icmp6) + sizeof(struct ip6_hdr));
+ if (m == NULL) {
+ IP6STAT_INC(ip6s_exthdrtoolong);
+ *mp = m;
+ return (-1);
+ }
}
icmp6 = (struct icmp6_hdr *)(mtod(m, caddr_t) + off);
eip6 = (struct ip6_hdr *)(icmp6 + 1);
@@ -921,11 +934,14 @@ icmp6_notify_error(struct mbuf **mp, int off, int icmp6len, int code)
case IPPROTO_HOPOPTS:
case IPPROTO_DSTOPTS:
case IPPROTO_AH:
- m = m_pullup(m, eoff + sizeof(struct ip6_ext));
- if (m == NULL) {
- IP6STAT_INC(ip6s_exthdrtoolong);
- *mp = m;
- return (-1);
+ if (m->m_len < eoff + sizeof(struct ip6_ext)) {
+ m = m_pullup(m, eoff +
+ sizeof(struct ip6_ext));
+ if (m == NULL) {
+ IP6STAT_INC(ip6s_exthdrtoolong);
+ *mp = m;
+ return (-1);
+ }
}
eh = (struct ip6_ext *)
(mtod(m, caddr_t) + eoff);
@@ -944,11 +960,13 @@ icmp6_notify_error(struct mbuf **mp, int off, int icmp6len, int code)
* information that depends on the final
* destination (e.g. path MTU).
*/
- m = m_pullup(m, eoff + sizeof(*rth));
- if (m == NULL) {
- IP6STAT_INC(ip6s_exthdrtoolong);
- *mp = m;
- return (-1);
+ if (m->m_len < eoff + sizeof(*rth)) {
+ m = m_pullup(m, eoff + sizeof(*rth));
+ if (m == NULL) {
+ IP6STAT_INC(ip6s_exthdrtoolong);
+ *mp = m;
+ return (-1);
+ }
}
rth = (struct ip6_rthdr *)
(mtod(m, caddr_t) + eoff);
@@ -965,11 +983,14 @@ icmp6_notify_error(struct mbuf **mp, int off, int icmp6len, int code)
rth->ip6r_type == IPV6_RTHDR_TYPE_0) {
int hops;
- m = m_pullup(m, eoff + rthlen);
- if (m == NULL) {
- IP6STAT_INC(ip6s_exthdrtoolong);
- *mp = m;
- return (-1);
+ if (m->m_len < eoff + rthlen) {
+ m = m_pullup(m, eoff + rthlen);
+ if (m == NULL) {
+ IP6STAT_INC(
+ ip6s_exthdrtoolong);
+ *mp = m;
+ return (-1);
+ }
}
rth0 = (struct ip6_rthdr0 *)
(mtod(m, caddr_t) + eoff);
@@ -982,11 +1003,14 @@ icmp6_notify_error(struct mbuf **mp, int off, int icmp6len, int code)
nxt = rth->ip6r_nxt;
break;
case IPPROTO_FRAGMENT:
- m = m_pullup(m, eoff + sizeof(struct ip6_frag));
- if (m == NULL) {
- IP6STAT_INC(ip6s_exthdrtoolong);
- *mp = m;
- return (-1);
+ if (m->m_len < eoff + sizeof(struct ip6_frag)) {
+ m = m_pullup(m, eoff +
+ sizeof(struct ip6_frag));
+ if (m == NULL) {
+ IP6STAT_INC(ip6s_exthdrtoolong);
+ *mp = m;
+ return (-1);
+ }
}
fh = (struct ip6_frag *)(mtod(m, caddr_t) +
eoff);
@@ -1295,11 +1319,14 @@ ni6_input(struct mbuf *m, int off, struct prison *pr)
mtx_unlock(&pr->pr_mtx);
if (!n || n->m_next || n->m_len == 0)
goto bad;
- m = m_pullup(m, off + sizeof(struct icmp6_nodeinfo) +
- subjlen);
- if (m == NULL) {
- IP6STAT_INC(ip6s_exthdrtoolong);
- goto bad;
+ if (m->m_len < off + sizeof(struct icmp6_nodeinfo) +
+ subjlen) {
+ m = m_pullup(m, off +
+ sizeof(struct icmp6_nodeinfo) + subjlen);
+ if (m == NULL) {
+ IP6STAT_INC(ip6s_exthdrtoolong);
+ goto bad;
+ }
}
/* ip6 possibly invalid but not used after. */
ni6 = (struct icmp6_nodeinfo *)(mtod(m, caddr_t) + off);
@@ -2201,10 +2228,12 @@ icmp6_redirect_input(struct mbuf *m, int off)
ip6 = mtod(m, struct ip6_hdr *);
icmp6len = ntohs(ip6->ip6_plen);
- m = m_pullup(m, off + icmp6len);
- if (m == NULL) {
- IP6STAT_INC(ip6s_exthdrtoolong);
- return;
+ if (m->m_len < off + icmp6len) {
+ m = m_pullup(m, off + icmp6len);
+ if (m == NULL) {
+ IP6STAT_INC(ip6s_exthdrtoolong);
+ return;
+ }
}
ip6 = mtod(m, struct ip6_hdr *);
nd_rd = (struct nd_redirect *)((caddr_t)ip6 + off);
diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c
index 8cf38525a0dc..22797ff5d3ba 100644
--- a/sys/netinet6/ip6_input.c
+++ b/sys/netinet6/ip6_input.c
@@ -969,20 +969,24 @@ ip6_hopopts_input(u_int32_t *plenp, u_int32_t *rtalertp,
struct ip6_hbh *hbh;
/* validation of the length of the header */
- m = m_pullup(m, off + sizeof(*hbh));
- if (m == NULL) {
- IP6STAT_INC(ip6s_exthdrtoolong);
- *mp = NULL;
- return (-1);
+ if (m->m_len < off + sizeof(*hbh)) {
+ m = m_pullup(m, off + sizeof(*hbh));
+ if (m == NULL) {
+ IP6STAT_INC(ip6s_exthdrtoolong);
+ *mp = NULL;
+ return (-1);
+ }
}
hbh = (struct ip6_hbh *)(mtod(m, caddr_t) + off);
hbhlen = (hbh->ip6h_len + 1) << 3;
- m = m_pullup(m, off + hbhlen);
- if (m == NULL) {
- IP6STAT_INC(ip6s_exthdrtoolong);
- *mp = NULL;
- return (-1);
+ if (m->m_len < off + hbhlen) {
+ m = m_pullup(m, off + hbhlen);
+ if (m == NULL) {
+ IP6STAT_INC(ip6s_exthdrtoolong);
+ *mp = NULL;
+ return (-1);
+ }
}
hbh = (struct ip6_hbh *)(mtod(m, caddr_t) + off);
off += hbhlen;
diff --git a/sys/netinet6/ip6_mroute.c b/sys/netinet6/ip6_mroute.c
index 660c2ef848b3..82ca908d4553 100644
--- a/sys/netinet6/ip6_mroute.c
+++ b/sys/netinet6/ip6_mroute.c
@@ -1745,10 +1745,12 @@ pim6_input(struct mbuf *m, int off, int proto, void *arg __unused)
* Make sure that the IP6 and PIM headers in contiguous memory, and
* possibly the PIM REGISTER header
*/
- m = m_pullup(m, off + minlen);
- if (m == NULL) {
- IP6STAT_INC(ip6s_exthdrtoolong);
- return (IPPROTO_DONE);
+ if (m->m_len < off + minlen) {
+ m = m_pullup(m, off + minlen);
+ if (m == NULL) {
+ IP6STAT_INC(ip6s_exthdrtoolong);
+ return (IPPROTO_DONE);
+ }
}
ip6 = mtod(m, struct ip6_hdr *);
pim = (struct pim *)((caddr_t)ip6 + off);
diff --git a/sys/netinet6/mld6.c b/sys/netinet6/mld6.c
index e5cb120fbef4..1698458462fb 100644
--- a/sys/netinet6/mld6.c
+++ b/sys/netinet6/mld6.c
@@ -1263,10 +1263,12 @@ mld_input(struct mbuf **mp, int off, int icmp6len)
ifp = m->m_pkthdr.rcvif;
/* Pullup to appropriate size. */
- m = m_pullup(m, off + sizeof(*mld));
- if (m == NULL) {
- ICMP6STAT_INC(icp6s_badlen);
- return (IPPROTO_DONE);
+ if (m->m_len < off + sizeof(*mld)) {
+ m = m_pullup(m, off + sizeof(*mld));
+ if (m == NULL) {
+ ICMP6STAT_INC(icp6s_badlen);
+ return (IPPROTO_DONE);
+ }
}
mld = (struct mld_hdr *)(mtod(m, uint8_t *) + off);
if (mld->mld_type == MLD_LISTENER_QUERY &&
@@ -1275,10 +1277,12 @@ mld_input(struct mbuf **mp, int off, int icmp6len)
} else {
mldlen = sizeof(struct mld_hdr);
}
- m = m_pullup(m, off + mldlen);
- if (m == NULL) {
- ICMP6STAT_INC(icp6s_badlen);
- return (IPPROTO_DONE);
+ if (m->m_len < off + mldlen) {
+ m = m_pullup(m, off + mldlen);
+ if (m == NULL) {
+ ICMP6STAT_INC(icp6s_badlen);
+ return (IPPROTO_DONE);
+ }
}
*mp = m;
ip6 = mtod(m, struct ip6_hdr *);
diff --git a/sys/netinet6/nd6_nbr.c b/sys/netinet6/nd6_nbr.c
index 153b1013ed56..28fefd160fb4 100644
--- a/sys/netinet6/nd6_nbr.c
+++ b/sys/netinet6/nd6_nbr.c
@@ -148,10 +148,12 @@ nd6_ns_input(struct mbuf *m, int off, int icmp6len)
goto bads;
}
- m = m_pullup(m, off + icmp6len);
- if (m == NULL) {
- IP6STAT_INC(ip6s_exthdrtoolong);
- return;
+ if (m->m_len < off + icmp6len) {
+ m = m_pullup(m, off + icmp6len);
+ if (m == NULL) {
+ IP6STAT_INC(ip6s_exthdrtoolong);
+ return;
+ }
}
ip6 = mtod(m, struct ip6_hdr *);
nd_ns = (struct nd_neighbor_solicit *)((caddr_t)ip6 + off);
@@ -652,10 +654,12 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len)
goto bad;
}
- m = m_pullup(m, off + icmp6len);
- if (m == NULL) {
- IP6STAT_INC(ip6s_exthdrtoolong);
- return;
+ if (m->m_len < off + icmp6len) {
+ m = m_pullup(m, off + icmp6len);
+ if (m == NULL) {
+ IP6STAT_INC(ip6s_exthdrtoolong);
+ return;
+ }
}
ip6 = mtod(m, struct ip6_hdr *);
nd_na = (struct nd_neighbor_advert *)((caddr_t)ip6 + off);
diff --git a/sys/netinet6/nd6_rtr.c b/sys/netinet6/nd6_rtr.c
index d334f977a7ab..2a1a66998d2e 100644
--- a/sys/netinet6/nd6_rtr.c
+++ b/sys/netinet6/nd6_rtr.c
@@ -190,10 +190,12 @@ nd6_rs_input(struct mbuf *m, int off, int icmp6len)
if (IN6_IS_ADDR_UNSPECIFIED(&saddr6))
goto freeit;
- m = m_pullup(m, off + icmp6len);
- if (m == NULL) {
- IP6STAT_INC(ip6s_exthdrtoolong);
- return;
+ if (m->m_len < off + icmp6len) {
+ m = m_pullup(m, off + icmp6len);
+ if (m == NULL) {
+ IP6STAT_INC(ip6s_exthdrtoolong);
+ return;
+ }
}
ip6 = mtod(m, struct ip6_hdr *);
nd_rs = (struct nd_router_solicit *)((caddr_t)ip6 + off);
@@ -388,10 +390,12 @@ nd6_ra_input(struct mbuf *m, int off, int icmp6len)
goto bad;
}
- m = m_pullup(m, off + icmp6len);
- if (m == NULL) {
- IP6STAT_INC(ip6s_exthdrtoolong);
- return;
+ if (m->m_len < off + icmp6len) {
+ m = m_pullup(m, off + icmp6len);
+ if (m == NULL) {
+ IP6STAT_INC(ip6s_exthdrtoolong);
+ return;
+ }
}
ip6 = mtod(m, struct ip6_hdr *);
nd_ra = (struct nd_router_advert *)((caddr_t)ip6 + off);
diff --git a/sys/netinet6/route6.c b/sys/netinet6/route6.c
index 4c488cba5f4a..72e42084eacc 100644
--- a/sys/netinet6/route6.c
+++ b/sys/netinet6/route6.c
@@ -83,11 +83,13 @@ route6_input(struct mbuf **mp, int *offp, int proto)
}
#endif
- m = m_pullup(m, off + sizeof(*rh));
- if (m == NULL) {
- IP6STAT_INC(ip6s_exthdrtoolong);
- *mp = NULL;
- return (IPPROTO_DONE);
+ if (m->m_len < off + sizeof(*rh)) {
+ m = m_pullup(m, off + sizeof(*rh));
+ if (m == NULL) {
+ IP6STAT_INC(ip6s_exthdrtoolong);
+ *mp = NULL;
+ return (IPPROTO_DONE);
+ }
}
ip6 = mtod(m, struct ip6_hdr *);
rh = (struct ip6_rthdr *)((caddr_t)ip6 + off);
diff --git a/sys/netinet6/sctp6_usrreq.c b/sys/netinet6/sctp6_usrreq.c
index e0bb5c8c12ef..dacf01760c6b 100644
--- a/sys/netinet6/sctp6_usrreq.c
+++ b/sys/netinet6/sctp6_usrreq.c
@@ -103,10 +103,12 @@ sctp6_input_with_port(struct mbuf **i_pak, int *offp, uint16_t port)
SCTP_STAT_INCR_COUNTER64(sctps_inpackets);
/* Get IP, SCTP, and first chunk header together in the first mbuf. */
offset = iphlen + sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);
- m = m_pullup(m, offset);
- if (m == NULL) {
- SCTP_STAT_INCR(sctps_hdrops);
- return (IPPROTO_DONE);
+ if (m->m_len < offset) {
+ m = m_pullup(m, offset);
+ if (m == NULL) {
+ SCTP_STAT_INCR(sctps_hdrops);
+ return (IPPROTO_DONE);
+ }
}
ip6 = mtod(m, struct ip6_hdr *);
sh = (struct sctphdr *)(mtod(m, caddr_t) + iphlen);
diff --git a/sys/netinet6/udp6_usrreq.c b/sys/netinet6/udp6_usrreq.c
index 64e5f6e3551f..124bded74a40 100644
--- a/sys/netinet6/udp6_usrreq.c
+++ b/sys/netinet6/udp6_usrreq.c
@@ -223,11 +223,13 @@ udp6_input(struct mbuf **mp, int *offp, int proto)
ifp = m->m_pkthdr.rcvif;
- m = m_pullup(m, off + sizeof(struct udphdr));
- if (m == NULL) {
- IP6STAT_INC(ip6s_exthdrtoolong);
- *mp = NULL;
- return (IPPROTO_DONE);
+ if (m->m_len < off + sizeof(struct udphdr)) {
+ m = m_pullup(m, off + sizeof(struct udphdr));
+ if (m == NULL) {
+ IP6STAT_INC(ip6s_exthdrtoolong);
+ *mp = NULL;
+ return (IPPROTO_DONE);
+ }
}
ip6 = mtod(m, struct ip6_hdr *);
uh = (struct udphdr *)((caddr_t)ip6 + off);