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
This commit is contained in:
Jonathan T. Looney
2018-10-09 13:26:06 +00:00
parent fc5e4199a6
commit 13c6ba6d94
3 changed files with 11 additions and 7 deletions
+7 -4
View File
@@ -2033,15 +2033,18 @@ lagg_lb_porttable(struct lagg_softc *sc, struct lagg_port *lp)
{
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_port *lp)
}
LAGG_RUNLOCK();
return (0);
return (rv);
}
static int
+3 -2
View File
@@ -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 @@ ip_dooptions(struct mbuf *m, int pass)
return (0);
bad:
NET_EPOCH_EXIT();
bad_unlocked:
icmp_error(m, type, code, 0, 0);
IPSTAT_INC(ips_badoptions);
return (1);
+1 -1
View File
@@ -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);
}
/*