⬢ DragonFlyBSD Kernel Audit
DF-4191 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/disk/sdhci/sdhci.c
+++ b/sys/dev/disk/sdhci/sdhci.c
@@ -1329,6 +1329,22 @@
 		if (err != 0) {
 			device_printf(slot->bus,
 			    "Dma load for ADMA2 fail: %d\n", err);
+			if (err == EINPROGRESS) {
+				/*
+				 * DF-4191: the load is deferred (bounce pages
+				 * exhausted) and busdma still owns the map and
+				 * the sdhci_adma2_getaddr() callback.  Falling
+				 * back to PIO would leave that callback armed
+				 * against the shared ADMA2 descriptor table,
+				 * where it can later rewrite descriptors of an
+				 * unrelated in-flight request (and leave the
+				 * map attached to a freed buffer).  Fail the
+				 * command instead.
+				 */
+				slot->flags &= ~SDHCI_USE_ADMA2;
+				slot->curcmd->error = MMC_ERR_INVALID;
+				return;
+			}
 		} else if (descs[0].address == 0) {
 			device_printf(slot->bus,
 			    "Dma load for ADMA2 fail, segment constraints\n");