diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c index d783c93a2abf..e5db364c8f6d 100644 --- a/sys/netinet/ip_carp.c +++ b/sys/netinet/ip_carp.c @@ -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); diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index 8d68770f5cb4..8e8c8b79a458 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -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); 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); diff --git a/sys/netipsec/xform_ah.c b/sys/netipsec/xform_ah.c index 2215d4f1c408..2ed9683a0572 100644 --- a/sys/netipsec/xform_ah.c +++ b/sys/netipsec/xform_ah.c @@ -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); diff --git a/sys/netipsec/xform_esp.c b/sys/netipsec/xform_esp.c index 918d98b6af22..235d87ae1d98 100644 --- a/sys/netipsec/xform_esp.c +++ b/sys/netipsec/xform_esp.c @@ -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);