⬢ DragonFlyBSD Kernel Audit
DF-4855 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/dev/agp/agp_amd64.c b/sys/dev/agp/agp_amd64.c
index 3d19e640..66b1a34f 100644
--- a/sys/dev/agp/agp_amd64.c
+++ b/sys/dev/agp/agp_amd64.c
@@ -204,14 +204,18 @@ agp_amd64_attach(device_t dev)
 	switch (pci_get_vendor(dev)) {
 	case 0x10b9:	/* ULi */
 		agp_amd64_uli_init(dev);
-		if (agp_amd64_uli_set_aperture(dev, sc->initial_aperture))
-			return (ENXIO);
+		if (agp_amd64_uli_set_aperture(dev, sc->initial_aperture)) {
+			error = ENXIO;
+			goto err;
+		}
 		break;
 
 	case 0x10de:	/* nVidia */
 		agp_amd64_nvidia_init(dev);
-		if (agp_amd64_nvidia_set_aperture(dev, sc->initial_aperture))
-			return (ENXIO);
+		if (agp_amd64_nvidia_set_aperture(dev, sc->initial_aperture)) {
+			error = ENXIO;
+			goto err;
+		}
 		break;
 
 	case 0x1106:	/* VIA */
@@ -219,8 +223,10 @@ agp_amd64_attach(device_t dev)
 		if (sc->via_agp) {
 			agp_amd64_via_init(dev);
 			if (agp_amd64_via_set_aperture(dev,
-			    sc->initial_aperture))
-				return (ENXIO);
+			    sc->initial_aperture)) {
+				error = ENXIO;
+				goto err;
+			}
 		}
 		break;
 	}
@@ -240,6 +246,18 @@ agp_amd64_attach(device_t dev)
 	agp_flush_cache();
 
 	return (0);
+
+err:
+	/*
+	 * agp_generic_attach() already published /dev/agpgart and
+	 * allocated the aperture resource; sc->gatt is allocated.
+	 * Undo everything or the cdev/resource/GATT leak on an
+	 * unattached device.
+	 */
+	agp_free_gatt(sc->gatt);
+	sc->gatt = NULL;
+	agp_generic_detach(dev);
+	return (error);
 }
 
 static int