⬢ DragonFlyBSD Kernel Audit
DF-4572 / fix.diff
← back to finding ↓ download raw
--- exca.c.orig	2026-09-21
+++ exca.c	2026-09-21
@@ exca_mem_map: release the window on the memreg error return
 	if (((rman_get_start(res) >> EXCA_MEMREG_WIN_SHIFT) & 0xff) != 0 &&
 	    (sc->flags & EXCA_HAS_MEMREG_WIN) == 0) {
 		device_printf(sc->dev, "Does not support mapping above 24M.");
+		sc->memalloc &= ~(1 << win);
 		return (1);
 	}
 
@@ exca_activate_resource: unwind the window if the parent activation fails
 int
 exca_activate_resource(struct exca_softc *exca, device_t child, int type,
     int rid, struct resource *res)
 {
 	int err;
+	int mapped = 0;
+
 	if (!(rman_get_flags(res) & RF_ACTIVE)) { /* not already activated */
 		switch (type) {
 		case SYS_RES_IOPORT:
 			err = exca_io_map(exca, PCCARD_WIDTH_AUTO, res);
+			mapped = (err == 0);
 			break;
 		case SYS_RES_MEMORY:
 			err = exca_mem_map(exca, PCCARD_A_MEM_COM, res);
+			mapped = (err == 0);
 			break;
 		default:
 			err = 0;
 			break;
 		}
 		if (err)
 			return (err);
 
 	}
-	return (BUS_ACTIVATE_RESOURCE(device_get_parent(exca->dev), child,
-		  type, rid, res));
+	err = BUS_ACTIVATE_RESOURCE(device_get_parent(exca->dev), child,
+		  type, rid, res);
+	if (err != 0 && mapped) {
+		switch (type) {
+		case SYS_RES_IOPORT:
+			exca_io_unmap_res(exca, res);
+			break;
+		case SYS_RES_MEMORY:
+			exca_mem_unmap_res(exca, res);
+			break;
+		}
+	}
+	return (err);
 }