Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 12 Nov 2019 15:46:29 +0000 (UTC)
From:      "Bjoern A. Zeeb" <bz@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r354643 - in head/sys: netinet netinet6
Message-ID:  <201911121546.xACFkTbo003756@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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);
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201911121546.xACFkTbo003756>