Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 9 Oct 2018 13:26:07 +0000 (UTC)
From:      "Jonathan T. Looney" <jtl@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r339251 - in head/sys: net netinet netinet6
Message-ID:  <201810091326.w99DQ7MN083891@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jtl
Date: Tue Oct  9 13:26:06 2018
New Revision: 339251
URL: https://svnweb.freebsd.org/changeset/base/339251

Log:
  There are three places where we return from a function which entered an
  epoch section without exiting that epoch section. This is bad for two
  reasons: the epoch section won't exit, and we will leave the epoch tracker
  from the stack on the epoch list.
  
  Fix the epoch leak by making sure we exit epoch sections before returning.
  
  Reviewed by:	ae, gallatin, mmacy
  Approved by:	re (gjb, kib)
  Sponsored by:	Netflix
  Differential Revision:	https://reviews.freebsd.org/D17450

Modified:
  head/sys/net/if_lagg.c
  head/sys/netinet/ip_options.c
  head/sys/netinet6/udp6_usrreq.c

Modified: head/sys/net/if_lagg.c
==============================================================================
--- head/sys/net/if_lagg.c	Tue Oct  9 10:49:19 2018	(r339250)
+++ head/sys/net/if_lagg.c	Tue Oct  9 13:26:06 2018	(r339251)
@@ -2033,15 +2033,18 @@ lagg_lb_porttable(struct lagg_softc *sc, struct lagg_p
 {
 	struct lagg_lb *lb = (struct lagg_lb *)sc->sc_psc;
 	struct lagg_port *lp_next;
-	int i = 0;
+	int i = 0, rv;
 
+	rv = 0;
 	bzero(&lb->lb_ports, sizeof(lb->lb_ports));
 	LAGG_RLOCK();
 	CK_SLIST_FOREACH(lp_next, &sc->sc_ports, lp_entries) {
 		if (lp_next == lp)
 			continue;
-		if (i >= LAGG_MAX_PORTS)
-			return (EINVAL);
+		if (i >= LAGG_MAX_PORTS) {
+			rv = EINVAL;
+			break;
+		}
 		if (sc->sc_ifflags & IFF_DEBUG)
 			printf("%s: port %s at index %d\n",
 			    sc->sc_ifname, lp_next->lp_ifp->if_xname, i);
@@ -2049,7 +2052,7 @@ lagg_lb_porttable(struct lagg_softc *sc, struct lagg_p
 	}
 	LAGG_RUNLOCK();
 
-	return (0);
+	return (rv);
 }
 
 static int

Modified: head/sys/netinet/ip_options.c
==============================================================================
--- head/sys/netinet/ip_options.c	Tue Oct  9 10:49:19 2018	(r339250)
+++ head/sys/netinet/ip_options.c	Tue Oct  9 13:26:06 2018	(r339251)
@@ -110,16 +110,16 @@ ip_dooptions(struct mbuf *m, int pass)
 	struct nhop4_extended nh_ext;
 	struct	sockaddr_in ipaddr = { sizeof(ipaddr), AF_INET };
 
-	NET_EPOCH_ENTER();
 	/* Ignore or reject packets with IP options. */
 	if (V_ip_doopts == 0)
 		return 0;
 	else if (V_ip_doopts == 2) {
 		type = ICMP_UNREACH;
 		code = ICMP_UNREACH_FILTER_PROHIB;
-		goto bad;
+		goto bad_unlocked;
 	}
 
+	NET_EPOCH_ENTER();
 	dst = ip->ip_dst;
 	cp = (u_char *)(ip + 1);
 	cnt = (ip->ip_hl << 2) - sizeof (struct ip);
@@ -388,6 +388,7 @@ dropit:
 	return (0);
 bad:
 	NET_EPOCH_EXIT();
+bad_unlocked:
 	icmp_error(m, type, code, 0, 0);
 	IPSTAT_INC(ips_badoptions);
 	return (1);

Modified: head/sys/netinet6/udp6_usrreq.c
==============================================================================
--- head/sys/netinet6/udp6_usrreq.c	Tue Oct  9 10:49:19 2018	(r339250)
+++ head/sys/netinet6/udp6_usrreq.c	Tue Oct  9 13:26:06 2018	(r339251)
@@ -434,8 +434,8 @@ udp6_input(struct mbuf **mp, int *offp, int proto)
 				INP_RUNLOCK(last);
 		} else
 			INP_RUNLOCK(last);
-		INP_INFO_RUNLOCK_ET(pcbinfo, et);
 	inp_lost:
+		INP_INFO_RUNLOCK_ET(pcbinfo, et);
 		return (IPPROTO_DONE);
 	}
 	/*



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