⬢ DragonFlyBSD Kernel Audit
DF-4402 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/raid/tws/tws_cam.c
+++ b/sys/dev/raid/tws/tws_cam.c
@@ -172,6 +172,7 @@
     cam_simq_release(devq);
     if (sc->sim == NULL) {
         tws_log(sc, CAM_SIM_ALLOC);
+        return(ENOMEM);   /* do not xpt_bus_register(NULL) */
     }
     /* Register the bus. */
     lockmgr(&sc->sim_lock, LK_EXCLUSIVE);
@@ -187,11 +188,18 @@
                          CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
         xpt_bus_deregister(cam_sim_path(sc->sim));
         cam_sim_free(sc->sim);
+        sc->sim = NULL;   /* so cam_detach will not double-free it */
         tws_log(sc, TWS_XPT_CREATE_PATH);
         lockmgr(&sc->sim_lock, LK_RELEASE);
         return(ENXIO);
     }
     if ((error = tws_bus_scan(sc))) {
+        /* undo the registration before failing the attach */
+        xpt_free_path(sc->path);
+        sc->path = NULL;
+        xpt_bus_deregister(cam_sim_path(sc->sim));
+        cam_sim_free(sc->sim);
+        sc->sim = NULL;
         tws_log(sc, TWS_BUS_SCAN_REQ);
         lockmgr(&sc->sim_lock, LK_RELEASE);
         return(error);