⬢ DragonFlyBSD Kernel Audit
DF-3414 / fix.diff
← back to finding ↓ download raw
--- a/sys/net/if_clone.c
+++ b/sys/net/if_clone.c
@@ -104 if_clone_destroy()
-	ifnet_lock();
-	ifp = ifunit(name);
-	ifnet_unlock();
-	if (ifp == NULL)
-		return (ENXIO);
-	if ((ifc = if_clone_lookup(ifp->if_dname)) == NULL)
-		return (EINVAL);
-	unit = ifp->if_dunit;
-	if (unit < ifc->ifc_minifs)
-		return (EINVAL);
-	if (ifc->ifc_destroy == NULL)
-		return (EOPNOTSUPP);
-
 	ifnet_lock();
+	ifp = ifunit(name);			/* DF-3414: hold the lock
+						 * across lookup..teardown */
+	if (ifp == NULL) { ifnet_unlock(); return (ENXIO); }
+	if ((ifc = if_clone_lookup(ifp->if_dname)) == NULL) {
+		ifnet_unlock(); return (EINVAL);
+	}
+	unit = ifp->if_dunit;
+	if (unit < ifc->ifc_minifs) { ifnet_unlock(); return (EINVAL); }
+	if (ifc->ifc_destroy == NULL) { ifnet_unlock(); return (EOPNOTSUPP); }
 	if_clone_free_unit(ifc, unit);
 	error = ifc->ifc_destroy(ifp);
 	if (error)
 		if_clone_alloc_unit(ifc, &unit);
 	ifnet_unlock();
 	(validated in the DF-3407 pack: stock kernel panics, patched runs
 	 2x120s of the same race clean)