aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx
diff options
context:
space:
mode:
authorAndrew Vasquez <andrew.vasquez@qlogic.com>2010-02-18 13:07:26 -0500
committerJames Bottomley <James.Bottomley@suse.de>2010-02-19 11:46:35 -0500
commit715848ca6fffeb6362a50887d9c26245bd5dfba9 (patch)
tree36ac766a39b039402f948b092f771bf00fbf3cf3 /drivers/scsi/qla2xxx
parent55e5ed273d758c62d2f1fad47c73716039f7c01c (diff)
[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')
-rw-r--r--drivers/scsi/qla2xxx/qla_attr.c2
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h1
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c38
3 files changed, 0 insertions, 41 deletions
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index 25596feea162..90d1e062ec4f 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -1531,8 +1531,6 @@ qla2x00_terminate_rport_io(struct fc_rport *rport)
1531 fcport->vha->hw->isp_ops->fabric_logout(fcport->vha, 1531 fcport->vha->hw->isp_ops->fabric_logout(fcport->vha,
1532 fcport->loop_id, fcport->d_id.b.domain, 1532 fcport->loop_id, fcport->d_id.b.domain,
1533 fcport->d_id.b.area, fcport->d_id.b.al_pa); 1533 fcport->d_id.b.area, fcport->d_id.b.al_pa);
1534
1535 qla2x00_abort_fcport_cmds(fcport);
1536} 1534}
1537 1535
1538static int 1536static int
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index b42e704bdca9..238f353b6b42 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -96,7 +96,6 @@ extern int qla2x00_post_uevent_work(struct scsi_qla_host *, u32);
96 96
97extern int qla81xx_restart_mpi_firmware(scsi_qla_host_t *); 97extern int qla81xx_restart_mpi_firmware(scsi_qla_host_t *);
98 98
99extern void qla2x00_abort_fcport_cmds(fc_port_t *);
100extern struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *, 99extern struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *,
101 struct qla_hw_data *); 100 struct qla_hw_data *);
102extern void qla2x00_free_host(struct scsi_qla_host *); 101extern void qla2x00_free_host(struct scsi_qla_host *);
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index d01daa3866f8..7964a11cca26 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)
682 return (return_status); 682 return (return_status);
683} 683}
684 684
685void
686qla2x00_abort_fcport_cmds(fc_port_t *fcport)
687{
688 int cnt;
689 unsigned long flags;
690 srb_t *sp;
691 scsi_qla_host_t *vha = fcport->vha;
692 struct qla_hw_data *ha = vha->hw;
693 struct req_que *req;
694
695 spin_lock_irqsave(&ha->hardware_lock, flags);
696 req = vha->req;
697 for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
698 sp = req->outstanding_cmds[cnt];
699 if (!sp)
700 continue;
701 if (sp->fcport != fcport)
702 continue;
703 if (sp->ctx)
704 continue;
705
706 spin_unlock_irqrestore(&ha->hardware_lock, flags);
707 if (ha->isp_ops->abort_command(sp)) {
708 DEBUG2(qla_printk(KERN_WARNING, ha,
709 "Abort failed -- %lx\n",
710 sp->cmd->serial_number));
711 } else {
712 if (qla2x00_eh_wait_on_command(sp->cmd) !=
713 QLA_SUCCESS)
714 DEBUG2(qla_printk(KERN_WARNING, ha,
715 "Abort failed while waiting -- %lx\n",
716 sp->cmd->serial_number));
717 }
718 spin_lock_irqsave(&ha->hardware_lock, flags);
719 }
720 spin_unlock_irqrestore(&ha->hardware_lock, flags);
721}
722
723/************************************************************************** 685/**************************************************************************
724* qla2xxx_eh_abort 686* qla2xxx_eh_abort
725* 687*