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); } /* _______________________________________________ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"