scsi: qla2xxx: Fix use after free in eh_abort path
commit 3d33b303d4f3b74a71bede5639ebba3cfd2a2b4d upstream.
In eh_abort path driver prematurely exits the call to upper layer. Check
whether command is aborted / completed by firmware before exiting the call.
9 [ffff8b1ebf803c00] page_fault at ffffffffb0389778
[exception RIP: qla2x00_status_entry+0x48d]
RIP: ffffffffc04fa62d RSP: ffff8b1ebf803cb0 RFLAGS: 00010082
RAX: 00000000ffffffff RBX: 00000000000e0000 RCX: 0000000000000000
RDX: 0000000000000000 RSI: 00000000000013d8 RDI: fffff3253db78440
RBP: ffff8b1ebf803dd0 R8: ffff8b1ebcd9b0c0 R9: 0000000000000000
R10: ffff8b1e38a30808 R11: 0000000000001000 R12: 00000000000003e9
R13: 0000000000000000 R14: ffff8b1ebcd9d740 R15: 0000000000000028
ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018
10 [ffff8b1ebf803cb0] enqueue_entity at ffffffffafce708f
11 [ffff8b1ebf803d00] enqueue_task_fair at ffffffffafce7b88
12 [ffff8b1ebf803dd8] qla24xx_process_response_queue at ffffffffc04fc9a6
[qla2xxx]
13 [ffff8b1ebf803e78] qla24xx_msix_rsp_q at ffffffffc04ff01b [qla2xxx]
14 [ffff8b1ebf803eb0] __handle_irq_event_percpu at ffffffffafd50714
Link: https://lore.kernel.org/r/20210908164622.19240-10-njavali@marvell.com
Fixes: f45bca8c50
("scsi: qla2xxx: Fix double scsi_done for abort path")
Cc: stable@vger.kernel.org
Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
Co-developed-by: David Jeffery <djeffery@redhat.com>
Signed-off-by: David Jeffery <djeffery@redhat.com>
Co-developed-by: Laurence Oberman <loberman@redhat.com>
Signed-off-by: Laurence Oberman <loberman@redhat.com>
Signed-off-by: Quinn Tran <qutran@marvell.com>
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:

committed by
Greg Kroah-Hartman

parent
37b15db1d8
commit
c1d31266de
@@ -1254,6 +1254,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
|
|||||||
uint32_t ratov_j;
|
uint32_t ratov_j;
|
||||||
struct qla_qpair *qpair;
|
struct qla_qpair *qpair;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
int fast_fail_status = SUCCESS;
|
||||||
|
|
||||||
if (qla2x00_isp_reg_stat(ha)) {
|
if (qla2x00_isp_reg_stat(ha)) {
|
||||||
ql_log(ql_log_info, vha, 0x8042,
|
ql_log(ql_log_info, vha, 0x8042,
|
||||||
@@ -1261,15 +1262,16 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
|
|||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Save any FAST_IO_FAIL value to return later if abort succeeds */
|
||||||
ret = fc_block_scsi_eh(cmd);
|
ret = fc_block_scsi_eh(cmd);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return ret;
|
fast_fail_status = ret;
|
||||||
|
|
||||||
sp = scsi_cmd_priv(cmd);
|
sp = scsi_cmd_priv(cmd);
|
||||||
qpair = sp->qpair;
|
qpair = sp->qpair;
|
||||||
|
|
||||||
if ((sp->fcport && sp->fcport->deleted) || !qpair)
|
if ((sp->fcport && sp->fcport->deleted) || !qpair)
|
||||||
return SUCCESS;
|
return fast_fail_status != SUCCESS ? fast_fail_status : FAILED;
|
||||||
|
|
||||||
spin_lock_irqsave(qpair->qp_lock_ptr, flags);
|
spin_lock_irqsave(qpair->qp_lock_ptr, flags);
|
||||||
sp->comp = ∁
|
sp->comp = ∁
|
||||||
@@ -1304,7 +1306,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
|
|||||||
__func__, ha->r_a_tov/10);
|
__func__, ha->r_a_tov/10);
|
||||||
ret = FAILED;
|
ret = FAILED;
|
||||||
} else {
|
} else {
|
||||||
ret = SUCCESS;
|
ret = fast_fail_status;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
Reference in New Issue
Block a user