⬢ DragonFlyBSD Kernel Audit
DF-5334 / fix.diff
← back to finding ↓ download raw
--- a/sys/bus/u4b/net/usb_ethernet.c	2026-10-03 00:29:42.632025953 +0000
+++ b/sys/bus/u4b/net/usb_ethernet.c	2026-10-03 00:29:47.275967257 +0000
@@ -269,6 +269,17 @@
 {
 	struct ifnet *ifp;
 
+	/*
+	 * Never attached: the calling driver's attach failed before
+	 * uether_ifattach() ran, so ue_lock and ue_tq were never set up
+	 * and the embedded arpcom/ifnet was never if_attach()ed.  On
+	 * DragonFly uether_getifp() returns the address of the embedded
+	 * ifnet and can never return NULL, so guard on ue_lock instead
+	 * (uether_ifattach() refuses to run when it is NULL).
+	 */
+	if (ue->ue_lock == NULL)
+		return;
+
 	/* wait for any post attach or other command to complete */
 	usb_proc_drain(&ue->ue_tq);
 
--- a/sys/bus/u4b/net/if_cdce.c	2026-10-03 00:29:42.632025953 +0000
+++ b/sys/bus/u4b/net/if_cdce.c	2026-10-03 00:29:53.895883585 +0000
@@ -608,7 +608,7 @@
 			}
 		} else {
 			device_printf(dev, "no data interface found\n");
-			goto detach;
+			goto detach_usb;
 		}
 	}
 
@@ -660,7 +660,7 @@
 	if (error || (i == 32)) {
 		device_printf(dev, "No valid alternate "
 		    "setting found\n");
-		goto detach;
+		goto detach_usb;
 	}
 
 	ued = usbd_find_descriptor
@@ -727,6 +727,18 @@
 	}
 	return (0);			/* success */
 
+detach_usb:
+	/*
+	 * Attach failed before uether_ifattach(): the usb_ether was never
+	 * initialised, so only tear down what may have been set up.  Do
+	 * NOT call cdce_detach() here - uether_ifdetach() would try to
+	 * lock through the NULL ue_lock and to detach the never-attached
+	 * embedded ifnet.
+	 */
+	usbd_transfer_unsetup(sc->sc_xfer, CDCE_N_TRANSFER);
+	lockuninit(&sc->sc_lock);
+	return (ENXIO);			/* failure */
+
 detach:
 	cdce_detach(dev);
 	return (ENXIO);			/* failure */