Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 14 May 2019 20:32:29 +0000 (UTC)
From:      Kyle Evans <kevans@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r347578 - head/sys/net
Message-ID:  <201905142032.x4EKWTpt074473@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kevans
Date: Tue May 14 20:32:29 2019
New Revision: 347578
URL: https://svnweb.freebsd.org/changeset/base/347578

Log:
  tuntap: Defer clearing if_softc until after if_detach
  
  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.
  
  Reported by:	markj
  MFC after:	3 days

Modified:
  head/sys/net/if_tuntap.c

Modified: head/sys/net/if_tuntap.c
==============================================================================
--- head/sys/net/if_tuntap.c	Tue May 14 20:31:06 2019	(r347577)
+++ head/sys/net/if_tuntap.c	Tue May 14 20:32:29 2019	(r347578)
@@ -537,9 +537,6 @@ tun_destroy(struct tuntap_softc *tp)
 		TUN_UNLOCK(tp);
 
 	CURVNET_SET(TUN2IFP(tp)->if_vnet);
-	sx_xlock(&tun_ioctl_sx);
-	TUN2IFP(tp)->if_softc = NULL;
-	sx_xunlock(&tun_ioctl_sx);
 
 	destroy_dev(tp->tun_dev);
 	seldrain(&tp->tun_rsel);
@@ -551,6 +548,9 @@ tun_destroy(struct tuntap_softc *tp)
 		bpfdetach(TUN2IFP(tp));
 		if_detach(TUN2IFP(tp));
 	}
+	sx_xlock(&tun_ioctl_sx);
+	TUN2IFP(tp)->if_softc = NULL;
+	sx_xunlock(&tun_ioctl_sx);
 	free_unr(tp->tun_drv->unrhdr, TUN2IFP(tp)->if_dunit);
 	if_free(TUN2IFP(tp));
 	mtx_destroy(&tp->tun_mtx);



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