svn commit: r213895 - stable/7/sys/net

Bjoern A. Zeeb bz at FreeBSD.org
Fri Oct 15 15:06:32 UTC 2010


Author: bz
Date: Fri Oct 15 15:06:32 2010
New Revision: 213895
URL: http://svn.freebsd.org/changeset/base/213895

Log:
  MFC r186391,186483,186497 (qingli, kmacy 21 months ago):
  
  r186391:
    Provide a condition variable to delay the cloned interface
    destroy operation until the referenced clone device has
    been closed by the process properly. The behavior is now
    consistently with the previous release.
  
  r186483:
    - Close a race during which the open flag could be cleared but the
      tun_softc would still be referenced by adding a separate TUN_CLOSED
      flag that is set after tunclose is done referencing it.
    - drop the tun_mtx after the flag check to avoid holding it across
      if_detach which can recurse in to if_tun.c
  
  r186497:
    The "tun?" dev need not be opened at all. One is allowed to perform
    the following operations, e.g.:
    1) ifconfig tun0 create
    2) ifconfig tun0 10.1.1.1 10.1.1.2
    3) route add -net 192.103.54.0/24 -iface tun0
    4) ifconfig tun0 destroy
    If cv wait on the TUN_CLOSED flag, then the last operation (4) will
    block forever.
  
    Revert the previous changes and fix the mtx_unlock() leak.
  
  PR:		kern/116837
  Submitted by:	Mikolaj Golub (to.my.trociny gmail.com)
  		(Not used the patch, just did the MFC)

Modified:
  stable/7/sys/net/if_tun.c
Directory Properties:
  stable/7/sys/   (props changed)
  stable/7/sys/cddl/contrib/opensolaris/   (props changed)
  stable/7/sys/contrib/dev/acpica/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)

Modified: stable/7/sys/net/if_tun.c
==============================================================================
--- stable/7/sys/net/if_tun.c	Fri Oct 15 15:00:30 2010	(r213894)
+++ stable/7/sys/net/if_tun.c	Fri Oct 15 15:06:32 2010	(r213895)
@@ -56,6 +56,7 @@
 #include <net/if_tun.h>
 
 #include <sys/queue.h>
+#include <sys/condvar.h>
 
 #include <security/mac/mac_framework.h>
 
@@ -92,6 +93,7 @@ struct tun_softc {
 	struct  sigio *tun_sigio;	/* information for async I/O */
 	struct	selinfo	tun_rsel;	/* read select */
 	struct mtx	tun_mtx;	/* protect mutable softc fields */
+	struct cv	tun_cv;		/* protect against ref'd dev destroy */
 };
 #define TUN2IFP(sc)	((sc)->tun_ifp)
 
@@ -242,8 +244,11 @@ tun_destroy(struct tun_softc *tp)
 	struct cdev *dev;
 
 	/* Unlocked read. */
-	KASSERT((tp->tun_flags & TUN_OPEN) == 0,
-	    ("tununits is out of sync - unit %d", TUN2IFP(tp)->if_dunit));
+	mtx_lock(&tp->tun_mtx);
+	if ((tp->tun_flags & TUN_OPEN) != 0)
+		cv_wait_unlock(&tp->tun_cv, &tp->tun_mtx);
+	else
+		mtx_unlock(&tp->tun_mtx);
 
 	dev = tp->tun_dev;
 	bpfdetach(TUN2IFP(tp));
@@ -252,6 +257,7 @@ tun_destroy(struct tun_softc *tp)
 	destroy_dev(dev);
 	knlist_destroy(&tp->tun_rsel.si_note);
 	mtx_destroy(&tp->tun_mtx);
+	cv_destroy(&tp->tun_cv);
 	free(tp, M_TUN);
 }
 
@@ -353,6 +359,7 @@ tuncreate(const char *name, struct cdev 
 
 	MALLOC(sc, struct tun_softc *, sizeof(*sc), M_TUN, M_WAITOK | M_ZERO);
 	mtx_init(&sc->tun_mtx, "tun_mtx", NULL, MTX_DEF);
+	cv_init(&sc->tun_cv, "tun_condvar");
 	sc->tun_flags = TUN_INITED;
 	sc->tun_dev = dev;
 	mtx_lock(&tunmtx);
@@ -472,6 +479,8 @@ tunclose(struct cdev *dev, int foo, int 
 	selwakeuppri(&tp->tun_rsel, PZERO + 1);
 	KNOTE_LOCKED(&tp->tun_rsel.si_note, 0);
 	TUNDEBUG (ifp, "closed\n");
+
+	cv_broadcast(&tp->tun_cv);
 	mtx_unlock(&tp->tun_mtx);
 	return (0);
 }


More information about the svn-src-all mailing list