Fix m_pullup() problem after removing PULLDOWN_TESTs and KAME EXT_*macros.
r354748-354750 replaced the KAME macros with m_pulldown() calls. Contrary to the rest of the network stack m_len checks before m_pulldown() were not put in placed (see r354748). Put these m_len checks in place for now (to go along with the style of the network stack since the initial commits). These are not put in for performance but to avoid an error scenario (even though it also will help performance at the moment as it avoid allocating an extra mbuf; not because of the unconditional function call). The observed error case went like this: (1) an mbuf with M_EXT arrives and we call m_pullup() unconditionally on it. (2) m_pullup() will call m_get() unless the requested length is larger than MHLEN (in which case it'll m_freem() the perfectly fine mbuf) and migrate the requested length of data and pkthdr into the new mbuf. (3) If m_get() succeeds, a further m_pullup() call going over MHLEN will fail. This was observed with failing auto-configuration as an RA packet of 200 bytes exceeded MHLEN and the m_pullup() called from nd6_ra_input() dropped the mbuf. (Re-)adding the m_len checks before m_pullup() calls avoids this problems with mbufs using external storage for now. MFC after: 3 weeks Sponsored by: Netflix
This commit is contained in:
parent
1b50b999f9
commit
a4adf6cc65
@ -566,12 +566,14 @@ carp6_input(struct mbuf **mp, int *offp, int proto)
|
||||
}
|
||||
|
||||
/* verify that we have a complete carp packet */
|
||||
len = m->m_len;
|
||||
m = m_pullup(m, *offp + sizeof(*ch));
|
||||
if (m == NULL) {
|
||||
CARPSTATS_INC(carps_badlen);
|
||||
CARP_DEBUG("%s: packet size %u too small\n", __func__, len);
|
||||
return (IPPROTO_DONE);
|
||||
if (m->m_len < *offp + sizeof(*ch)) {
|
||||
len = m->m_len;
|
||||
m = m_pullup(m, *offp + sizeof(*ch));
|
||||
if (m == NULL) {
|
||||
CARPSTATS_INC(carps_badlen);
|
||||
CARP_DEBUG("%s: packet size %u too small\n", __func__, len);
|
||||
return (IPPROTO_DONE);
|
||||
}
|
||||
}
|
||||
ch = (struct carp_header *)(mtod(m, caddr_t) + *offp);
|
||||
|
||||
|
@ -517,11 +517,13 @@ tcp6_input(struct mbuf **mp, int *offp, int proto)
|
||||
struct ip6_hdr *ip6;
|
||||
|
||||
m = *mp;
|
||||
m = m_pullup(m, *offp + sizeof(struct tcphdr));
|
||||
if (m == NULL) {
|
||||
*mp = m;
|
||||
TCPSTAT_INC(tcps_rcvshort);
|
||||
return (IPPROTO_DONE);
|
||||
if (m->m_len < *offp + sizeof(struct tcphdr)) {
|
||||
m = m_pullup(m, *offp + sizeof(struct tcphdr));
|
||||
if (m == NULL) {
|
||||
*mp = m;
|
||||
TCPSTAT_INC(tcps_rcvshort);
|
||||
return (IPPROTO_DONE);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -708,10 +710,12 @@ tcp_input(struct mbuf **mp, int *offp, int proto)
|
||||
if (off > sizeof (struct tcphdr)) {
|
||||
#ifdef INET6
|
||||
if (isipv6) {
|
||||
m = m_pullup(m, off0 + off);
|
||||
if (m == NULL) {
|
||||
TCPSTAT_INC(tcps_rcvshort);
|
||||
return (IPPROTO_DONE);
|
||||
if (m->m_len < off0 + off) {
|
||||
m = m_pullup(m, off0 + off);
|
||||
if (m == NULL) {
|
||||
TCPSTAT_INC(tcps_rcvshort);
|
||||
return (IPPROTO_DONE);
|
||||
}
|
||||
}
|
||||
ip6 = mtod(m, struct ip6_hdr *);
|
||||
th = (struct tcphdr *)((caddr_t)ip6 + off0);
|
||||
|
@ -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;
|
||||
|
@ -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 *);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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 *);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -575,12 +575,14 @@ ah_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff)
|
||||
/* Figure out header size. */
|
||||
rplen = HDRSIZE(sav);
|
||||
|
||||
m = m_pullup(m, skip + rplen);
|
||||
if (m == NULL) {
|
||||
DPRINTF(("ah_input: cannot pullup header\n"));
|
||||
AHSTAT_INC(ahs_hdrops); /*XXX*/
|
||||
error = ENOBUFS;
|
||||
goto bad;
|
||||
if (m->m_len < skip + rplen) {
|
||||
m = m_pullup(m, skip + rplen);
|
||||
if (m == NULL) {
|
||||
DPRINTF(("ah_input: cannot pullup header\n"));
|
||||
AHSTAT_INC(ahs_hdrops); /*XXX*/
|
||||
error = ENOBUFS;
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
ah = (struct newah *)(mtod(m, caddr_t) + skip);
|
||||
|
||||
|
@ -308,12 +308,14 @@ esp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff)
|
||||
goto bad;
|
||||
}
|
||||
|
||||
m = m_pullup(m, skip + sizeof(*esp));
|
||||
if (m == NULL) {
|
||||
DPRINTF(("%s: cannot pullup header\n", __func__));
|
||||
ESPSTAT_INC(esps_hdrops); /*XXX*/
|
||||
error = ENOBUFS;
|
||||
goto bad;
|
||||
if (m->m_len < skip + sizeof(*esp)) {
|
||||
m = m_pullup(m, skip + sizeof(*esp));
|
||||
if (m == NULL) {
|
||||
DPRINTF(("%s: cannot pullup header\n", __func__));
|
||||
ESPSTAT_INC(esps_hdrops); /*XXX*/
|
||||
error = ENOBUFS;
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
esp = (struct newesp *)(mtod(m, caddr_t) + skip);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user