diff options
author | Andrew Vasquez <andrew.vasquez@qlogic.com> | 2010-02-18 18:07:26 (GMT) |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-02-19 16:46:35 (GMT) |
commit | 715848ca6fffeb6362a50887d9c26245bd5dfba9 (patch) | |
tree | 36ac766a39b039402f948b092f771bf00fbf3cf3 /drivers/scsi/qla2xxx/qla_os.c | |
parent | 55e5ed273d758c62d2f1fad47c73716039f7c01c (diff) | |
download | linux-fsl-qoriq-715848ca6fffeb6362a50887d9c26245bd5dfba9.tar.xz |
[SCSI] qla2xxx: Correct use-after-free issue in terminate_rport_io callback.
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>
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_os.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 38 |
1 files changed, 0 insertions, 38 deletions
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index d01daa3..7964a11 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -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 * |