From owner-svn-src-head@freebsd.org Sun Dec 1 00:22:07 2019 Return-Path: Delivered-To: svn-src-head@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id C2AE11BDADE; Sun, 1 Dec 2019 00:22:07 +0000 (UTC) (envelope-from bz@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 47QTTC5XZsz3DwW; Sun, 1 Dec 2019 00:22:07 +0000 (UTC) (envelope-from bz@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id A12956666; Sun, 1 Dec 2019 00:22:07 +0000 (UTC) (envelope-from bz@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id xB10M7Zp001092; Sun, 1 Dec 2019 00:22:07 GMT (envelope-from bz@FreeBSD.org) Received: (from bz@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id xB10M4qa001075; Sun, 1 Dec 2019 00:22:04 GMT (envelope-from bz@FreeBSD.org) Message-Id: <201912010022.xB10M4qa001075@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: bz set sender to bz@FreeBSD.org using -f From: "Bjoern A. Zeeb" Date: Sun, 1 Dec 2019 00:22:04 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r355254 - in head/sys: netinet netinet6 netipsec X-SVN-Group: head X-SVN-Commit-Author: bz X-SVN-Commit-Paths: in head/sys: netinet netinet6 netipsec X-SVN-Commit-Revision: 355254 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 01 Dec 2019 00:22:07 -0000 Author: bz Date: Sun Dec 1 00:22:04 2019 New Revision: 355254 URL: https://svnweb.freebsd.org/changeset/base/355254 Log: 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 Modified: head/sys/netinet/ip_carp.c head/sys/netinet/tcp_input.c head/sys/netinet6/dest6.c head/sys/netinet6/frag6.c head/sys/netinet6/icmp6.c head/sys/netinet6/ip6_input.c head/sys/netinet6/ip6_mroute.c head/sys/netinet6/mld6.c head/sys/netinet6/nd6_nbr.c head/sys/netinet6/nd6_rtr.c head/sys/netinet6/route6.c head/sys/netinet6/sctp6_usrreq.c head/sys/netinet6/udp6_usrreq.c head/sys/netipsec/xform_ah.c head/sys/netipsec/xform_esp.c Modified: head/sys/netinet/ip_carp.c ============================================================================== --- head/sys/netinet/ip_carp.c Sat Nov 30 21:11:17 2019 (r355253) +++ head/sys/netinet/ip_carp.c Sun Dec 1 00:22:04 2019 (r355254) @@ -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); Modified: head/sys/netinet/tcp_input.c ============================================================================== --- head/sys/netinet/tcp_input.c Sat Nov 30 21:11:17 2019 (r355253) +++ head/sys/netinet/tcp_input.c Sun Dec 1 00:22:04 2019 (r355254) @@ -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); Modified: head/sys/netinet6/dest6.c ============================================================================== --- head/sys/netinet6/dest6.c Sat Nov 30 21:11:17 2019 (r355253) +++ head/sys/netinet6/dest6.c Sun Dec 1 00:22:04 2019 (r355254) @@ -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; Modified: head/sys/netinet6/frag6.c ============================================================================== --- head/sys/netinet6/frag6.c Sat Nov 30 21:11:17 2019 (r355253) +++ head/sys/netinet6/frag6.c Sun Dec 1 00:22:04 2019 (r355254) @@ -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 *); Modified: head/sys/netinet6/icmp6.c ============================================================================== --- head/sys/netinet6/icmp6.c Sat Nov 30 21:11:17 2019 (r355253) +++ head/sys/netinet6/icmp6.c Sun Dec 1 00:22:04 2019 (r355254) @@ -317,10 +317,12 @@ icmp6_error(struct mbuf *m, int type, int code, int pa 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 icmp 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 icmp 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 icmp * 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 icmp 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 icmp 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); Modified: head/sys/netinet6/ip6_input.c ============================================================================== --- head/sys/netinet6/ip6_input.c Sat Nov 30 21:11:17 2019 (r355253) +++ head/sys/netinet6/ip6_input.c Sun Dec 1 00:22:04 2019 (r355254) @@ -969,20 +969,24 @@ ip6_hopopts_input(u_int32_t *plenp, u_int32_t *rtalert 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; Modified: head/sys/netinet6/ip6_mroute.c ============================================================================== --- head/sys/netinet6/ip6_mroute.c Sat Nov 30 21:11:17 2019 (r355253) +++ head/sys/netinet6/ip6_mroute.c Sun Dec 1 00:22:04 2019 (r355254) @@ -1745,10 +1745,12 @@ pim6_input(struct mbuf *m, int off, int proto, void *a * 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); Modified: head/sys/netinet6/mld6.c ============================================================================== --- head/sys/netinet6/mld6.c Sat Nov 30 21:11:17 2019 (r355253) +++ head/sys/netinet6/mld6.c Sun Dec 1 00:22:04 2019 (r355254) @@ -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 *); Modified: head/sys/netinet6/nd6_nbr.c ============================================================================== --- head/sys/netinet6/nd6_nbr.c Sat Nov 30 21:11:17 2019 (r355253) +++ head/sys/netinet6/nd6_nbr.c Sun Dec 1 00:22:04 2019 (r355254) @@ -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); Modified: head/sys/netinet6/nd6_rtr.c ============================================================================== --- head/sys/netinet6/nd6_rtr.c Sat Nov 30 21:11:17 2019 (r355253) +++ head/sys/netinet6/nd6_rtr.c Sun Dec 1 00:22:04 2019 (r355254) @@ -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); Modified: head/sys/netinet6/route6.c ============================================================================== --- head/sys/netinet6/route6.c Sat Nov 30 21:11:17 2019 (r355253) +++ head/sys/netinet6/route6.c Sun Dec 1 00:22:04 2019 (r355254) @@ -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); Modified: head/sys/netinet6/sctp6_usrreq.c ============================================================================== --- head/sys/netinet6/sctp6_usrreq.c Sat Nov 30 21:11:17 2019 (r355253) +++ head/sys/netinet6/sctp6_usrreq.c Sun Dec 1 00:22:04 2019 (r355254) @@ -103,10 +103,12 @@ sctp6_input_with_port(struct mbuf **i_pak, int *offp, 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); Modified: head/sys/netinet6/udp6_usrreq.c ============================================================================== --- head/sys/netinet6/udp6_usrreq.c Sat Nov 30 21:11:17 2019 (r355253) +++ head/sys/netinet6/udp6_usrreq.c Sun Dec 1 00:22:04 2019 (r355254) @@ -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); Modified: head/sys/netipsec/xform_ah.c ============================================================================== --- head/sys/netipsec/xform_ah.c Sat Nov 30 21:11:17 2019 (r355253) +++ head/sys/netipsec/xform_ah.c Sun Dec 1 00:22:04 2019 (r355254) @@ -575,12 +575,14 @@ ah_input(struct mbuf *m, struct secasvar *sav, int ski /* 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); Modified: head/sys/netipsec/xform_esp.c ============================================================================== --- head/sys/netipsec/xform_esp.c Sat Nov 30 21:11:17 2019 (r355253) +++ head/sys/netipsec/xform_esp.c Sun Dec 1 00:22:04 2019 (r355254) @@ -308,12 +308,14 @@ esp_input(struct mbuf *m, struct secasvar *sav, int sk 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);