⬢ DragonFlyBSD Kernel Audit
DF-3426 / fix.diff
← back to finding ↓ download raw
--- a/sys/net/netmap/netmap_generic.c
+++ b/sys/net/netmap/netmap_generic.c
@@ -518,6 +518,21 @@
              * ring->avail == 0 || j != k
              */
             tx_ret = generic_xmit_frame(ifp, m, addr, len, ring_nr);
+            /*
+             * DF-3426: generic_xmit_frame() transfers full ownership of
+             * the mbuf to ifq_dispatch()/the driver -- the refcount
+             * retention the original design relied on is #if 0'd out
+             * in generic_xmit_frame() (netmap_freebsd.c:131-135), and
+             * on both the success and the failure path the mbuf is
+             * gone (queued for the driver / dropped by
+             * ifsq_enqueue_locked).  Clear the slot now so the pool
+             * never aliases driver-owned or already-freed memory.
+             * The replenish paths (generic_netmap_tx_clean() at :361
+             * and the !m branch above) already handle NULL entries,
+             * and generic_set_tx_event() treats NULL as "event
+             * already pending".
+             */
+            kring->tx_pool[j] = NULL;
             if (unlikely(tx_ret)) {
                 RD(5, "start_xmit failed: err %d [%u,%u,%u,%u]",
 			tx_ret, kring->nr_ntc, j, k, kring->nr_hwavail);