From owner-svn-src-head@freebsd.org Tue Nov 12 15:46:31 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 0D3BB1B1366; Tue, 12 Nov 2019 15:46:31 +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 47CBtZ6Yznz3D4C; Tue, 12 Nov 2019 15:46:30 +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 C01A01E95; Tue, 12 Nov 2019 15:46:30 +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 xACFkUat003764; Tue, 12 Nov 2019 15:46:30 GMT (envelope-from bz@FreeBSD.org) Received: (from bz@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id xACFkTbo003756; Tue, 12 Nov 2019 15:46:29 GMT (envelope-from bz@FreeBSD.org) Message-Id: <201911121546.xACFkTbo003756@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: bz set sender to bz@FreeBSD.org using -f From: "Bjoern A. Zeeb" Date: Tue, 12 Nov 2019 15:46:29 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r354643 - in head/sys: netinet netinet6 X-SVN-Group: head X-SVN-Commit-Author: bz X-SVN-Commit-Paths: in head/sys: netinet netinet6 X-SVN-Commit-Revision: 354643 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: Tue, 12 Nov 2019 15:46:31 -0000 Author: bz Date: Tue Nov 12 15:46:28 2019 New Revision: 354643 URL: https://svnweb.freebsd.org/changeset/base/354643 Log: netinet*: update *mp to pass the proper value back In ip6_[direct_]input() we are looping over the extension headers to deal with the next header. We pass a pointer to an mbuf pointer to the handling functions. In certain cases the mbuf can be updated there and we need to pass the new one back. That missing in dest6_input() and route6_input(). In tcp6_input() we should also update it before we call tcp_input(). In addition to that mark the mbuf NULL all the times when we return that we are done with handling the packet and no next header should be checked (IPPROTO_DONE). This will eventually allow us to assert proper behaviour and catch the above kind of errors more easily, expecting *mp to always be set. This change is extracted from a larger patch and not an exhaustive change across the entire stack yet. PR: 240135 Reported by: prabhakar.lakhera gmail.com MFC after: 3 weeks Sponsored by: Netflix Modified: 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/route6.c head/sys/netinet6/udp6_usrreq.c Modified: head/sys/netinet/tcp_input.c ============================================================================== --- head/sys/netinet/tcp_input.c Tue Nov 12 15:34:19 2019 (r354642) +++ head/sys/netinet/tcp_input.c Tue Nov 12 15:46:28 2019 (r354643) @@ -530,11 +530,13 @@ tcp6_input(struct mbuf **mp, int *offp, int proto) ifa_free(&ia6->ia_ifa); icmp6_error(m, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADDR, (caddr_t)&ip6->ip6_dst - (caddr_t)ip6); + *mp = NULL; return (IPPROTO_DONE); } if (ia6) ifa_free(&ia6->ia_ifa); + *mp = m; return (tcp_input(mp, offp, proto)); } #endif /* INET6 */ Modified: head/sys/netinet6/dest6.c ============================================================================== --- head/sys/netinet6/dest6.c Tue Nov 12 15:34:19 2019 (r354642) +++ head/sys/netinet6/dest6.c Tue Nov 12 15:46:28 2019 (r354643) @@ -113,17 +113,21 @@ dest6_input(struct mbuf **mp, int *offp, int proto) default: /* unknown option */ optlen = ip6_unknown_opt(opt, m, opt - mtod(m, u_int8_t *)); - if (optlen == -1) + if (optlen == -1) { + *mp = NULL; return (IPPROTO_DONE); + } optlen += 2; break; } } *offp = off; + *mp = m; return (dstopts->ip6d_nxt); bad: m_freem(m); + *mp = NULL; return (IPPROTO_DONE); } Modified: head/sys/netinet6/frag6.c ============================================================================== --- head/sys/netinet6/frag6.c Tue Nov 12 15:34:19 2019 (r354642) +++ head/sys/netinet6/frag6.c Tue Nov 12 15:46:28 2019 (r354643) @@ -419,6 +419,7 @@ frag6_input(struct mbuf **mp, int *offp, int proto) if (ip6->ip6_plen == 0) { icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, offset); in6_ifstat_inc(dstifp, ifs6_reass_fail); + *mp = NULL; return (IPPROTO_DONE); } @@ -433,6 +434,7 @@ frag6_input(struct mbuf **mp, int *offp, int proto) icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, offsetof(struct ip6_hdr, ip6_plen)); in6_ifstat_inc(dstifp, ifs6_reass_fail); + *mp = NULL; return (IPPROTO_DONE); } @@ -476,6 +478,7 @@ frag6_input(struct mbuf **mp, int *offp, int proto) offsetof(struct ip6_hdr, ip6_plen)); in6_ifstat_inc(dstifp, ifs6_reass_fail); IP6STAT_INC(ip6s_fragdropped); + *mp = NULL; return (IPPROTO_DONE); } @@ -611,6 +614,7 @@ frag6_input(struct mbuf **mp, int *offp, int proto) icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, offset - sizeof(struct ip6_frag) + offsetof(struct ip6_frag, ip6f_offlg)); + *mp = NULL; return (IPPROTO_DONE); } } else if (fragoff + frgpartlen > IPV6_MAXPACKET) { @@ -627,6 +631,7 @@ frag6_input(struct mbuf **mp, int *offp, int proto) icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, offset - sizeof(struct ip6_frag) + offsetof(struct ip6_frag, ip6f_offlg)); + *mp = NULL; return (IPPROTO_DONE); } @@ -777,6 +782,7 @@ postinsert: frag6_freef(q6, bucket); } IP6QB_UNLOCK(bucket); + *mp = NULL; return (IPPROTO_DONE); } plen += af6->ip6af_frglen; @@ -788,6 +794,7 @@ postinsert: frag6_freef(q6, bucket); } IP6QB_UNLOCK(bucket); + *mp = NULL; return (IPPROTO_DONE); } @@ -877,6 +884,7 @@ postinsert: #ifdef RSS /* Queue/dispatch for reprocessing. */ netisr_dispatch(NETISR_IPV6_DIRECT, m); + *mp = NULL; return (IPPROTO_DONE); #endif @@ -892,6 +900,7 @@ dropfrag2: in6_ifstat_inc(dstifp, ifs6_reass_fail); IP6STAT_INC(ip6s_fragdropped); m_freem(m); + *mp = NULL; return (IPPROTO_DONE); } Modified: head/sys/netinet6/icmp6.c ============================================================================== --- head/sys/netinet6/icmp6.c Tue Nov 12 15:34:19 2019 (r354642) +++ head/sys/netinet6/icmp6.c Tue Nov 12 15:46:28 2019 (r354643) @@ -617,8 +617,10 @@ icmp6_input(struct mbuf **mp, int *offp, int proto) */ if ((ip6->ip6_hlim != 1) || (m->m_flags & M_RTALERT_MLD) == 0) goto freeit; - if (mld_input(m, off, icmp6len) != 0) + if (mld_input(m, off, icmp6len) != 0) { + *mp = NULL; return (IPPROTO_DONE); + } /* m stays. */ break; @@ -853,6 +855,7 @@ icmp6_input(struct mbuf **mp, int *offp, int proto) deliver: if (icmp6_notify_error(&m, off, icmp6len, code) != 0) { /* In this case, m should've been freed. */ + *mp = NULL; return (IPPROTO_DONE); } break; @@ -869,11 +872,13 @@ icmp6_input(struct mbuf **mp, int *offp, int proto) /* deliver the packet to appropriate sockets */ icmp6_rip6_input(&m, *offp); - return IPPROTO_DONE; + *mp = m; + return (IPPROTO_DONE); freeit: m_freem(m); - return IPPROTO_DONE; + *mp = NULL; + return (IPPROTO_DONE); } static int @@ -1106,6 +1111,7 @@ icmp6_notify_error(struct mbuf **mp, int off, int icmp freeit: m_freem(m); + *mp = NULL; return (-1); } @@ -1918,6 +1924,7 @@ icmp6_rip6_input(struct mbuf **mp, int off) fromsa.sin6_addr = ip6->ip6_src; if (sa6_recoverscope(&fromsa)) { m_freem(m); + *mp = NULL; return (IPPROTO_DONE); } @@ -2041,7 +2048,8 @@ icmp6_rip6_input(struct mbuf **mp, int off) m_freem(m); IP6STAT_DEC(ip6s_delivered); } - return IPPROTO_DONE; + *mp = NULL; + return (IPPROTO_DONE); } /* Modified: head/sys/netinet6/ip6_input.c ============================================================================== --- head/sys/netinet6/ip6_input.c Tue Nov 12 15:34:19 2019 (r354642) +++ head/sys/netinet6/ip6_input.c Tue Nov 12 15:46:28 2019 (r354643) @@ -1010,8 +1010,10 @@ ip6_hopopts_input(u_int32_t *plenp, u_int32_t *rtalert off += hbhlen; hbhlen -= sizeof(struct ip6_hbh); if (ip6_process_hopopts(m, (u_int8_t *)hbh + sizeof(struct ip6_hbh), - hbhlen, rtalertp, plenp) < 0) + hbhlen, rtalertp, plenp) < 0) { + *mp = NULL; return (-1); + } *offp = off; *mp = m; Modified: head/sys/netinet6/route6.c ============================================================================== --- head/sys/netinet6/route6.c Tue Nov 12 15:34:19 2019 (r354642) +++ head/sys/netinet6/route6.c Tue Nov 12 15:46:28 2019 (r354643) @@ -110,9 +110,11 @@ route6_input(struct mbuf **mp, int *offp, int proto) IP6STAT_INC(ip6s_badoptions); icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, (caddr_t)&rh->ip6r_type - (caddr_t)ip6); + *mp = NULL; return (IPPROTO_DONE); } *offp += rhlen; + *mp = m; return (rh->ip6r_nxt); } Modified: head/sys/netinet6/udp6_usrreq.c ============================================================================== --- head/sys/netinet6/udp6_usrreq.c Tue Nov 12 15:34:19 2019 (r354642) +++ head/sys/netinet6/udp6_usrreq.c Tue Nov 12 15:46:28 2019 (r354643) @@ -394,8 +394,11 @@ udp6_input(struct mbuf **mp, int *offp, int proto) else UDP_PROBE(receive, NULL, last, ip6, last, uh); - if (udp6_append(last, n, off, fromsa)) + if (udp6_append(last, n, off, fromsa)) { + /* XXX-BZ do we leak m here? */ + *mp = NULL; return (IPPROTO_DONE); + } } INP_RUNLOCK(last); } @@ -434,6 +437,7 @@ udp6_input(struct mbuf **mp, int *offp, int proto) INP_RUNLOCK(last); } else INP_RUNLOCK(last); + *mp = NULL; return (IPPROTO_DONE); } /* @@ -501,6 +505,7 @@ udp6_input(struct mbuf **mp, int *offp, int proto) if (V_udp_blackhole) goto badunlocked; icmp6_error(m, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOPORT, 0); + *mp = NULL; return (IPPROTO_DONE); } INP_RLOCK_ASSERT(inp); @@ -509,6 +514,7 @@ udp6_input(struct mbuf **mp, int *offp, int proto) if (up->u_rxcslen == 0 || up->u_rxcslen > ulen) { INP_RUNLOCK(inp); m_freem(m); + *mp = NULL; return (IPPROTO_DONE); } } @@ -518,11 +524,13 @@ udp6_input(struct mbuf **mp, int *offp, int proto) UDP_PROBE(receive, NULL, inp, ip6, inp, uh); if (udp6_append(inp, m, off, fromsa) == 0) INP_RUNLOCK(inp); + *mp = NULL; return (IPPROTO_DONE); badunlocked: if (m) m_freem(m); + *mp = NULL; return (IPPROTO_DONE); }