
From: Arun Easi <aeasi@marvell.com> mainline inclusion from mainline-v6.0-rc1 commit c39587bc0abaf16593f7abcdf8aeec3c038c7d52 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/ICG8KR CVE: CVE-2022-50098 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... -------------------------------- Ensure SRB is returned during I/O timeout error escalation. If that is not possible fail the escalation path. Following crash stack was seen: BUG: unable to handle kernel paging request at 0000002f56aa90f8 IP: qla_chk_edif_rx_sa_delete_pending+0x14/0x30 [qla2xxx] Call Trace: ? qla2x00_status_entry+0x19f/0x1c50 [qla2xxx] ? qla2x00_start_sp+0x116/0x1170 [qla2xxx] ? dma_pool_alloc+0x1d6/0x210 ? mempool_alloc+0x54/0x130 ? qla24xx_process_response_queue+0x548/0x12b0 [qla2xxx] ? qla_do_work+0x2d/0x40 [qla2xxx] ? process_one_work+0x14c/0x390 Link: https://lore.kernel.org/r/20220616053508.27186-6-njavali@marvell.com Fixes: d74595278f4a ("scsi: qla2xxx: Add multiple queue pair functionality.") Cc: stable@vger.kernel.org Signed-off-by: Arun Easi <aeasi@marvell.com> Signed-off-by: Nilesh Javali <njavali@marvell.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> Conflicts: drivers/scsi/qla2xxx/qla_os.c [Only pick the part modified by the mainline patch. The conflicts are mainly focus on the function qla2xxx_eh_device_reset and qla2xxx_eh_target_reset. They call __qla2xxx_eh_generic_reset inside themselves, conflicts with the mainline, so only pick the "return FAILED" from the mainline patch, and ignore the context conflicts which is irrelevant to this CVE.] Signed-off-by: Zicheng Qu <quzicheng@huawei.com> --- drivers/scsi/qla2xxx/qla_os.c | 45 +++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 8e9d386146ac..64ce20e41f9d 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -1342,21 +1342,23 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) return ret; } -int -qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *vha, unsigned int t, - uint64_t l, enum nexus_wait_type type) +/* + * Returns: QLA_SUCCESS or QLA_FUNCTION_FAILED. + */ +static int +__qla2x00_eh_wait_for_pending_commands(struct qla_qpair *qpair, unsigned int t, + uint64_t l, enum nexus_wait_type type) { int cnt, match, status; unsigned long flags; - struct qla_hw_data *ha = vha->hw; - struct req_que *req; + scsi_qla_host_t *vha = qpair->vha; + struct req_que *req = qpair->req; srb_t *sp; struct scsi_cmnd *cmd; status = QLA_SUCCESS; - spin_lock_irqsave(&ha->hardware_lock, flags); - req = vha->req; + spin_lock_irqsave(qpair->qp_lock_ptr, flags); for (cnt = 1; status == QLA_SUCCESS && cnt < req->num_outstanding_cmds; cnt++) { sp = req->outstanding_cmds[cnt]; @@ -1383,12 +1385,32 @@ qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *vha, unsigned int t, if (!match) continue; - spin_unlock_irqrestore(&ha->hardware_lock, flags); + spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); status = qla2x00_eh_wait_on_command(cmd); - spin_lock_irqsave(&ha->hardware_lock, flags); + spin_lock_irqsave(qpair->qp_lock_ptr, flags); } - spin_unlock_irqrestore(&ha->hardware_lock, flags); + spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); + + return status; +} + +int +qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *vha, unsigned int t, + uint64_t l, enum nexus_wait_type type) +{ + struct qla_qpair *qpair; + struct qla_hw_data *ha = vha->hw; + int i, status = QLA_SUCCESS; + status = __qla2x00_eh_wait_for_pending_commands(ha->base_qpair, t, l, + type); + for (i = 0; status == QLA_SUCCESS && i < ha->max_qpairs; i++) { + qpair = ha->queue_pair_map[i]; + if (!qpair) + continue; + status = __qla2x00_eh_wait_for_pending_commands(qpair, t, l, + type); + } return status; } @@ -1415,6 +1437,9 @@ __qla2xxx_eh_generic_reset(char *name, enum nexus_wait_type type, if (err != 0) return err; + if (fcport->deleted) + return FAILED; + ql_log(ql_log_info, vha, 0x8009, "%s RESET ISSUED nexus=%ld:%d:%llu cmd=%p.\n", name, vha->host_no, cmd->device->id, cmd->device->lun, cmd); -- 2.34.1