DragonFlyBSD Kernel Audit
DF-0998 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/bus/u4b/wlan/if_rum.c b/sys/bus/u4b/wlan/if_rum.c
@@ -1054,10 +1054,21 @@
 			STAILQ_REMOVE_HEAD(&sc->tx_q, next);
 			m = data->m;
 
-			if (m->m_pkthdr.len > (int)(MCLBYTES + RT2573_TX_DESC_SIZE)) {
+			/*
+			 * The TX DMA buffer layout is [TX_DESC (24 bytes) |
+			 * mbuf payload] and the buffer's total capacity is
+			 * MCLBYTES + RT2573_TX_DESC_SIZE + 8 bytes
+			 * (rum_config[RUM_BULK_WR].bufsize).  The mbuf
+			 * payload therefore must not exceed MCLBYTES, or
+			 * usbd_m_copy_in() writes past the DMA buffer
+			 * (24 + len > bufsize when len > MCLBYTES).  The old
+			 * clamp used MCLBYTES + RT2573_TX_DESC_SIZE, allowing
+			 * a 16-byte overwrite.  See DF-0998.
+			 */
+			if (m->m_pkthdr.len > (int)MCLBYTES) {
 				DPRINTFN(0, "data overflow, %u bytes\n",
 				    m->m_pkthdr.len);
-				m->m_pkthdr.len = (MCLBYTES + RT2573_TX_DESC_SIZE);
+				m->m_pkthdr.len = MCLBYTES;
 			}
 			pc = usbd_xfer_get_frame(xfer, 0);
 			usbd_copy_in(pc, 0, &data->desc, RT2573_TX_DESC_SIZE);