Date: Wed, 22 May 2019 22:34:35 +0000 (UTC) From: Kyle Evans <kevans@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org Subject: svn commit: r348124 - stable/12/sys/net Message-ID: <201905222234.x4MMYZho035654@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kevans Date: Wed May 22 22:34:35 2019 New Revision: 348124 URL: https://svnweb.freebsd.org/changeset/base/348124 Log: MFC r347578: tun/tap: Defer clearing if_softc until after if_detach (Commit massaged to match stable structure; tun and tap have been merged in head) r346670 added an sx to close a race between the ifioctl handler and interface destruction. Unfortunately, it clears if_softc immediately after the interface is closed, but before if_detach has been invoked. Any time before detachment, an interface that's part of a bridge may still receive traffic that's pushed through tunstart/tunstart_l2 and promptly lead to a panic because if_softc is now NULL. Fix it by deferring the clearing of if_softc until after the interface has detached and thus been removed from the bridge. if_softc still gets cleared in case another thread has already entered the ioctl handler before it's replaced with ifdead_ioctl. Modified: stable/12/sys/net/if_tap.c stable/12/sys/net/if_tun.c Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/net/if_tap.c ============================================================================== --- stable/12/sys/net/if_tap.c Wed May 22 21:47:26 2019 (r348123) +++ stable/12/sys/net/if_tap.c Wed May 22 22:34:35 2019 (r348124) @@ -223,15 +223,17 @@ tap_destroy(struct tap_softc *tp) struct ifnet *ifp = tp->tap_ifp; CURVNET_SET(ifp->if_vnet); - sx_xlock(&tap_ioctl_sx); - ifp->if_softc = NULL; - sx_xunlock(&tap_ioctl_sx); destroy_dev(tp->tap_dev); seldrain(&tp->tap_rsel); knlist_clear(&tp->tap_rsel.si_note, 0); knlist_destroy(&tp->tap_rsel.si_note); ether_ifdetach(ifp); + + sx_xlock(&tap_ioctl_sx); + ifp->if_softc = NULL; + sx_xunlock(&tap_ioctl_sx); + if_free(ifp); mtx_destroy(&tp->tap_mtx); Modified: stable/12/sys/net/if_tun.c ============================================================================== --- stable/12/sys/net/if_tun.c Wed May 22 21:47:26 2019 (r348123) +++ stable/12/sys/net/if_tun.c Wed May 22 22:34:35 2019 (r348124) @@ -278,13 +278,15 @@ tun_destroy(struct tun_softc *tp) mtx_unlock(&tp->tun_mtx); CURVNET_SET(TUN2IFP(tp)->if_vnet); - sx_xlock(&tun_ioctl_sx); - TUN2IFP(tp)->if_softc = NULL; - sx_xunlock(&tun_ioctl_sx); dev = tp->tun_dev; bpfdetach(TUN2IFP(tp)); if_detach(TUN2IFP(tp)); + + sx_xlock(&tun_ioctl_sx); + TUN2IFP(tp)->if_softc = NULL; + sx_xunlock(&tun_ioctl_sx); + free_unr(tun_unrhdr, TUN2IFP(tp)->if_dunit); if_free(TUN2IFP(tp)); destroy_dev(dev);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201905222234.x4MMYZho035654>