⬢ DragonFlyBSD Kernel Audit
DF-5046 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/raid/ida/ida_disk.c
+++ b/sys/dev/raid/ida/ida_disk.c
@@ -107,6 +107,7 @@
 	drv = idad_getsoftc(dev);
 	if (drv == NULL)
 		return (ENXIO);
+	drv->opencount++;
 #if 0
 	bzero(&info, sizeof(info));
 	info.d_media_blksize = drv->secsize;		/* mandatory */
@@ -132,6 +133,7 @@
 	drv = idad_getsoftc(dev);
 	if (drv == NULL)
 		return (ENXIO);
+	drv->opencount--;
 	return (0);
 }
 
@@ -305,6 +307,16 @@
 	struct idad_softc *drv;
 
 	drv = (struct idad_softc *)device_get_softc(dev);
+
+	/*
+	 * DF-5046: do not free the softc under open descriptors or
+	 * in-flight bios; disk_destroy() does not drain them.
+	 */
+	if (drv->opencount > 0) {
+		device_printf(dev, "disk is open (count %d)\n",
+		    drv->opencount);
+		return (EBUSY);
+	}
 	devstat_remove_entry(&drv->stats);
 	disk_destroy(&drv->disk);
 	return (0);
--- a/sys/dev/raid/ida/idavar.h
+++ b/sys/dev/raid/ida/idavar.h
@@ -179,6 +179,7 @@
 	int		secsize;
 	int		secperunit;
 	int		flags;
+	int		opencount;	/* DF-5046: open fds gate detach */
 };
 
 struct ida_board {