[SCSI] qla2xxx: Correct use-after-free issue in terminate_rport_io callback.
authorAndrew Vasquez <andrew.vasquez@qlogic.com>
Thu, 18 Feb 2010 18:07:26 +0000 (10:07 -0800)
committerJames Bottomley <James.Bottomley@suse.de>
Fri, 19 Feb 2010 16:46:35 +0000 (10:46 -0600)
The explicit logout (LOGO) issued at the end of the callback will
flush (via normal scsi_cmnd->done()) any outstanding commands
(FCP2) the firmware is holding.  While iterating through the
outstanding_cmnd array in qla2x00_abort_fcport_cmds(), locking
and unlocking of the hardware spinlock, opens-up the driver to
cases where the processed SRB (sp) could be used after the
command completed from interrupt context.

Cc: stable@kernel.org
Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
Signed-off-by: Giridhar Malavali <giridhar.malavali@qlogic.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
drivers/scsi/qla2xxx/qla_attr.c
drivers/scsi/qla2xxx/qla_gbl.h
drivers/scsi/qla2xxx/qla_os.c

index 25596feea1623de35d353c22bd91b82554a0220f..90d1e062ec4f13461bc428d41c17f4e03e007932 100644 (file)
@@ -1531,8 +1531,6 @@ qla2x00_terminate_rport_io(struct fc_rport *rport)
                fcport->vha->hw->isp_ops->fabric_logout(fcport->vha,
                        fcport->loop_id, fcport->d_id.b.domain,
                        fcport->d_id.b.area, fcport->d_id.b.al_pa);
-
-       qla2x00_abort_fcport_cmds(fcport);
 }
 
 static int
index b42e704bdca994f7b8bc6c34c297190eb61062a1..238f353b6b42a66de1ca580b82e7a341a1bf14b6 100644 (file)
@@ -96,7 +96,6 @@ extern int qla2x00_post_uevent_work(struct scsi_qla_host *, u32);
 
 extern int qla81xx_restart_mpi_firmware(scsi_qla_host_t *);
 
-extern void qla2x00_abort_fcport_cmds(fc_port_t *);
 extern struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *,
        struct qla_hw_data *);
 extern void qla2x00_free_host(struct scsi_qla_host *);
index d01daa3866f8fade98cbd6708308d30f718922c9..7964a11cca2662a933799ec5c462103072ad654e 100644 (file)
@@ -682,44 +682,6 @@ qla2x00_wait_for_loop_ready(scsi_qla_host_t *vha)
        return (return_status);
 }
 
-void
-qla2x00_abort_fcport_cmds(fc_port_t *fcport)
-{
-       int cnt;
-       unsigned long flags;
-       srb_t *sp;
-       scsi_qla_host_t *vha = fcport->vha;
-       struct qla_hw_data *ha = vha->hw;
-       struct req_que *req;
-
-       spin_lock_irqsave(&ha->hardware_lock, flags);
-       req = vha->req;
-       for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
-               sp = req->outstanding_cmds[cnt];
-               if (!sp)
-                       continue;
-               if (sp->fcport != fcport)
-                       continue;
-               if (sp->ctx)
-                       continue;
-
-               spin_unlock_irqrestore(&ha->hardware_lock, flags);
-               if (ha->isp_ops->abort_command(sp)) {
-                       DEBUG2(qla_printk(KERN_WARNING, ha,
-                       "Abort failed --  %lx\n",
-                       sp->cmd->serial_number));
-               } else {
-                       if (qla2x00_eh_wait_on_command(sp->cmd) !=
-                               QLA_SUCCESS)
-                               DEBUG2(qla_printk(KERN_WARNING, ha,
-                               "Abort failed while waiting --  %lx\n",
-                               sp->cmd->serial_number));
-               }
-               spin_lock_irqsave(&ha->hardware_lock, flags);
-       }
-       spin_unlock_irqrestore(&ha->hardware_lock, flags);
-}
-
 /**************************************************************************
 * qla2xxx_eh_abort
 *