⬢ DragonFlyBSD Kernel Audit
DF-4317 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/netif/lge/if_lge.c
+++ b/sys/dev/netif/lge/if_lge.c
@@ -804,6 +804,15 @@
 	struct lge_jslot *entry = (struct lge_jslot *)arg;
 	struct lge_softc *sc = entry->lge_sc;
 
+	/*
+	 * Serialize the check-then-increment against lge_jfree()'s
+	 * decrement-and-recycle (same lock lge_jfree/lge_jalloc use),
+	 * otherwise a racing lge_jfree can recycle this slot onto the
+	 * free list between our check and our increment, and lge_jalloc
+	 * will hand the buffer to a new RX descriptor while the shared
+	 * mbuf still references it.
+	 */
+	lwkt_serialize_enter(&sc->lge_jslot_serializer);
 	if (&sc->lge_cdata.lge_jslots[entry->lge_slot] != entry)
 		panic("lge_jref: asked to reference buffer "
 		    "that we don't manage!");
@@ -811,6 +820,7 @@
 		panic("lge_jref: buffer already free!");
 	else
 		atomic_add_int(&entry->lge_inuse, 1);
+	lwkt_serialize_exit(&sc->lge_jslot_serializer);
 }
 
 /*