mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-21 08:53:41 +00:00
[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>
This commit is contained in:
parent
55e5ed273d
commit
715848ca6f
@ -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
|
||||
|
@ -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 *);
|
||||
|
@ -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
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user