⬢ DragonFlyBSD Kernel Audit
DF-5520 / fix.diff
← back to finding ↓ download raw
--- a/sys/bus/isa/x86_64/isa_dma.c	2026-10-06 20:51:42.700616456 +0000
+++ b/sys/bus/isa/x86_64/isa_dma.c	2026-10-06 20:52:35.127935134 +0000
@@ -169,12 +169,12 @@
 
 	if (dma_busy & (1 << chan)) {
 		dma_busy &= ~(1 << chan);
-		/* 
-		 * XXX We should also do "dma_bounced &= (1 << chan);"
-		 * because we are acting on behalf of isa_dmadone() which
-		 * was not called to end the last DMA operation.  This does
-		 * not matter now, but it may in the future.
+		/*
+		 * We are acting on behalf of isa_dmadone() which was not
+		 * called to end the last DMA operation; drop any stale
+		 * bounce state so it cannot poison the next transfer.
 		 */
+		dma_bounced &= ~(1 << chan);
 	}
 
 	dma_inuse &= ~(1 << chan);
@@ -350,8 +350,17 @@
 
 	if (dma_bounced & (1 << chan)) {
 		/* copy bounce buffer on read */
-		if (flags & ISADMA_READ)
-			bcopy(dma_bouncebuf[chan], addr, nbytes);
+		if (flags & ISADMA_READ) {
+			u_int n = (u_int)nbytes;
+
+			if (n > dma_bouncebufsize[chan]) {
+				kprintf("isa_dmadone: count %u exceeds bounce "
+					"buffer size %u, clamping\n",
+					n, dma_bouncebufsize[chan]);
+				n = dma_bouncebufsize[chan];
+			}
+			bcopy(dma_bouncebuf[chan], addr, n);
+		}
 
 		dma_bounced &= ~(1 << chan);
 	}