Author: kevans
Date: Wed May 22 22:56:05 2019
New Revision: 348126
URL: https://svnweb.freebsd.org/changeset/base/348126

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.
  
  Approved by:  re (kib)

Modified:
  stable/11/sys/net/if_tap.c
  stable/11/sys/net/if_tun.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/net/if_tap.c
==============================================================================
--- stable/11/sys/net/if_tap.c  Wed May 22 22:55:27 2019        (r348125)
+++ stable/11/sys/net/if_tap.c  Wed May 22 22:56:05 2019        (r348126)
@@ -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/11/sys/net/if_tun.c
==============================================================================
--- stable/11/sys/net/if_tun.c  Wed May 22 22:55:27 2019        (r348125)
+++ stable/11/sys/net/if_tun.c  Wed May 22 22:56:05 2019        (r348126)
@@ -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);
_______________________________________________
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"

Reply via email to