From 224fe6574bafae89368c757d51a02d00eb09b45c Mon Sep 17 00:00:00 2001 From: scottl Date: Tue, 5 Apr 2005 15:08:19 +0000 Subject: Fix a use-after-free problem in atapi_cb(). Add some necessary synchronization to the XPT_PATH_INQ op. Don't leak locks on failure in XPT_SCSIIO. Correctly fix the CAMDEBUG message. --- sys/dev/ata/atapi-cam.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'sys/dev/ata/atapi-cam.c') diff --git a/sys/dev/ata/atapi-cam.c b/sys/dev/ata/atapi-cam.c index 6c3189f..4c5eaa7 100644 --- a/sys/dev/ata/atapi-cam.c +++ b/sys/dev/ata/atapi-cam.c @@ -340,9 +340,11 @@ atapi_action(struct cam_sim *sim, union ccb *ccb) cpi->base_transfer_speed = 3300; if (softc->ata_ch && tid != CAM_TARGET_WILDCARD) { + mtx_lock(&softc->state_lock); if (softc->atadev[tid] == NULL) { ccb->ccb_h.status = CAM_DEV_NOT_THERE; xpt_done(ccb); + mtx_unlock(&softc->state_lock); return; } switch (softc->atadev[ccb_h->target_id]->mode) { @@ -375,6 +377,7 @@ atapi_action(struct cam_sim *sim, union ccb *ccb) default: break; } + mtx_unlock(&softc->state_lock); } ccb->ccb_h.status = CAM_REQ_CMP; xpt_done(ccb); @@ -595,15 +598,19 @@ action_oom: ata_free_request(request); if (hcb != NULL) free_hcb(hcb); + mtx_unlock(&softc->state_lock); + mtx_lock(&Giant); xpt_print_path(ccb_h->path); printf("out of memory, freezing queue.\n"); softc->flags |= RESOURCE_SHORTAGE; xpt_freeze_simq(sim, /*count*/ 1); + mtx_unlock(&Giant); ccb_h->status = CAM_REQUEUE_REQ; xpt_done(ccb); return; action_invalid: + mtx_unlock(&softc->state_lock); ccb_h->status = CAM_REQ_INVALID; xpt_done(ccb); return; @@ -619,14 +626,16 @@ atapi_poll(struct cam_sim *sim) static void atapi_cb(struct ata_request *request) { + struct atapi_xpt_softc *scp; struct atapi_hcb *hcb; struct ccb_scsiio *csio; u_int32_t rc; hcb = (struct atapi_hcb *)request->driver; + scp = hcb->softc; csio = &hcb->ccb->csio; -#ifdef XXXCAMDEBUG +#ifdef CAMDEBUG # define err (request->u.atapi.sense_key) if (CAM_DEBUGGED(csio->ccb_h.path, CAM_DEBUG_CDB)) { printf("atapi_cb: hcb@%p error = %02x: (sk = %02x%s%s%s)\n", @@ -635,7 +644,7 @@ atapi_cb(struct ata_request *request) (err & 2) ? " EOM" : "", (err & 1) ? " ILI" : ""); printf("dev %s: cmd %02x status %02x result %02x\n", - request->device->name, request->u.atapi.ccb[0], + device_get_nameunit(request->dev), request->u.atapi.ccb[0], request->status, request->result); } #endif @@ -685,9 +694,9 @@ atapi_cb(struct ata_request *request) } } - mtx_lock(&hcb->softc->state_lock); + mtx_lock(&scp->state_lock); free_hcb_and_ccb_done(hcb, rc); - mtx_unlock(&hcb->softc->state_lock); + mtx_unlock(&scp->state_lock); ata_free_request(request); } -- cgit v1.1