DragonFlyBSD Kernel Audit
DF-2507 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/dev/disk/nata/atapi-fd.c b/sys/dev/disk/nata/atapi-fd.c
--- a/sys/dev/disk/nata/atapi-fd.c
+++ b/sys/dev/disk/nata/atapi-fd.c
@@ -173,6 +173,16 @@
     
     if (((atadev->unit == ATA_MASTER) && !(ch->devices & ATA_ATAPI_MASTER)) ||
 	((atadev->unit == ATA_SLAVE) && !(ch->devices & ATA_ATAPI_SLAVE))) {
+	/* The device vanished during channel reset.  Previously this only did
+	 * device_set_ivars(NULL)+kfree(), orphaning the disk, devstat and
+	 * /dev/afdN cdev with dangling pointers into freed memory (the later
+	 * afd_detach early-returns ENXIO on the NULL ivars and skips all
+	 * cleanup).  Tear down properly here, mirroring afd_detach, so nothing
+	 * references the freed softc.  See DF-2507. */
+	disk_invalidate(&fdp->disk);
+	disk_destroy(&fdp->disk);
+	ata_fail_requests(dev);
+	devstat_remove_entry(&fdp->stats);
 	device_set_ivars(dev, NULL);
 	kfree(fdp, M_AFD);
 	return 1;