⬢ DragonFlyBSD Kernel Audit
DF-5380 / fix.diff
← back to finding ↓ download raw
--- a/sys/bus/u4b/quirk/usb_quirk.c
+++ b/sys/bus/u4b/quirk/usb_quirk.c	2026-10-03 20:23:45.706029830 +0000
@@ -779,13 +779,22 @@
 usb_quirk_get_entry(uint16_t vid, uint16_t pid,
     uint16_t lo_rev, uint16_t hi_rev, uint8_t do_alloc)
 {
+	struct usb_quirk_entry *p;
 	uint16_t x;
 
 	KKASSERT(lockowned(&usb_quirk_lock));
 
 	if ((vid | pid | lo_rev | hi_rev) == 0) {
-		/* all zero - special case */
-		return (usb_quirks + USB_DEV_QUIRKS_MAX - 1);
+		/*
+		 * All-zero key: use the reserved last slot only while it
+		 * is still free.  Never alias a slot that has meanwhile
+		 * been allocated to a real device entry - otherwise
+		 * all-zero ADD/REMOVE silently mutate that entry.
+		 */
+		p = usb_quirks + USB_DEV_QUIRKS_MAX - 1;
+		if ((p->vid | p->pid | p->lo_rev | p->hi_rev) == 0)
+			return (p);
+		return (NULL);
 	}
 	/* search for an existing entry */
 	for (x = 0; x != USB_DEV_QUIRKS_MAX; x++) {
@@ -817,6 +826,10 @@
 		usb_quirks[x].lo_rev = lo_rev;
 		usb_quirks[x].hi_rev = hi_rev;
 
+		/* never inherit stale sub-quirks from a previous use */
+		memset(usb_quirks[x].quirks, 0,
+		    sizeof(usb_quirks[x].quirks));
+
 		return (usb_quirks + x);
 	}