⬢ DragonFlyBSD Kernel Audit
DF-4438 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/raid/mrsas/mrsas_cam.c
+++ b/sys/dev/raid/mrsas/mrsas_cam.c
@@ -151,6 +151,7 @@
     {
         cam_simq_release(devq);
         cam_sim_free(sc->sim_0);
+        sc->sim_0 = NULL;  /* DF-4438: don't let mrsas_cam_detach re-free */
         lockmgr(&sc->sim_lock, LK_RELEASE); 
         return(ENXIO);
     }
@@ -160,6 +161,7 @@
         xpt_bus_deregister(cam_sim_path(sc->sim_0));
         cam_simq_release(devq);
         cam_sim_free(sc->sim_0);
+        sc->sim_0 = NULL;  /* DF-4438 */
         lockmgr(&sc->sim_lock, LK_RELEASE); 
         return(ENXIO);
     }
@@ -174,12 +176,14 @@
     cam_simq_release(devq);
     if (sc->sim_1 == NULL){
         device_printf(sc->mrsas_dev, "Cannot register SIM\n");
+        cam_simq_release(devq);  /* DF-4438: drop caller's devq ref */
         return(ENXIO);
     }
 
     lockmgr(&sc->sim_lock, LK_EXCLUSIVE);
     if (xpt_bus_register(sc->sim_1, 1) != CAM_SUCCESS){
 	cam_sim_free(sc->sim_1);
+        sc->sim_1 = NULL;  /* DF-4438 */
         lockmgr(&sc->sim_lock, LK_RELEASE);
         return(ENXIO);
     }
@@ -188,6 +192,7 @@
                          CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
         xpt_bus_deregister(cam_sim_path(sc->sim_1));
         cam_sim_free(sc->sim_1);
+        sc->sim_1 = NULL;  /* DF-4438 */
         lockmgr(&sc->sim_lock, LK_RELEASE);
         return(ENXIO);
     }
@@ -216,12 +221,14 @@
     if (sc->sim_0) {
         xpt_bus_deregister(cam_sim_path(sc->sim_0));
         cam_sim_free(sc->sim_0);
+        sc->sim_0 = NULL;  /* DF-4438 */
     }
     if (sc->path_1)
         xpt_free_path(sc->path_1);
     if (sc->sim_1) {
         xpt_bus_deregister(cam_sim_path(sc->sim_1));
         cam_sim_free(sc->sim_1);
+        sc->sim_1 = NULL;  /* DF-4438 */
     }
     lockmgr(&sc->sim_lock, LK_RELEASE);
 }