Skip to content

Commit 2be1d4f

Browse files
Justin Teemartinkpetersen
authored andcommitted
scsi: lpfc: Validate hdwq pointers before dereferencing in reset/errata paths
When the HBA is undergoing a reset or is handling an errata event, NULL ptr dereference crashes may occur in routines such as lpfc_sli_flush_io_rings(), lpfc_dev_loss_tmo_callbk(), or lpfc_abort_handler(). Add NULL ptr checks before dereferencing hdwq pointers that may have been freed due to operations colliding with a reset or errata event handler. Signed-off-by: Justin Tee <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Martin K. Petersen <[email protected]>
1 parent f1bfe32 commit 2be1d4f

File tree

3 files changed

+24
-3
lines changed

3 files changed

+24
-3
lines changed

drivers/scsi/lpfc/lpfc_hbadisc.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,8 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
175175
ndlp->nlp_state, ndlp->fc4_xpt_flags);
176176

177177
/* Don't schedule a worker thread event if the vport is going down. */
178-
if (test_bit(FC_UNLOADING, &vport->load_flag)) {
178+
if (test_bit(FC_UNLOADING, &vport->load_flag) ||
179+
!test_bit(HBA_SETUP, &phba->hba_flag)) {
179180
spin_lock_irqsave(&ndlp->lock, iflags);
180181
ndlp->rport = NULL;
181182

drivers/scsi/lpfc/lpfc_scsi.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5555,11 +5555,20 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
55555555

55565556
iocb = &lpfc_cmd->cur_iocbq;
55575557
if (phba->sli_rev == LPFC_SLI_REV4) {
5558-
pring_s4 = phba->sli4_hba.hdwq[iocb->hba_wqidx].io_wq->pring;
5559-
if (!pring_s4) {
5558+
/* if the io_wq & pring are gone, the port was reset. */
5559+
if (!phba->sli4_hba.hdwq[iocb->hba_wqidx].io_wq ||
5560+
!phba->sli4_hba.hdwq[iocb->hba_wqidx].io_wq->pring) {
5561+
lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP,
5562+
"2877 SCSI Layer I/O Abort Request "
5563+
"IO CMPL Status x%x ID %d LUN %llu "
5564+
"HBA_SETUP %d\n", FAILED,
5565+
cmnd->device->id,
5566+
(u64)cmnd->device->lun,
5567+
test_bit(HBA_SETUP, &phba->hba_flag));
55605568
ret = FAILED;
55615569
goto out_unlock_hba;
55625570
}
5571+
pring_s4 = phba->sli4_hba.hdwq[iocb->hba_wqidx].io_wq->pring;
55635572
spin_lock(&pring_s4->ring_lock);
55645573
}
55655574
/* the command is in process of being cancelled */

drivers/scsi/lpfc/lpfc_sli.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4687,6 +4687,17 @@ lpfc_sli_flush_io_rings(struct lpfc_hba *phba)
46874687
/* Look on all the FCP Rings for the iotag */
46884688
if (phba->sli_rev >= LPFC_SLI_REV4) {
46894689
for (i = 0; i < phba->cfg_hdw_queue; i++) {
4690+
if (!phba->sli4_hba.hdwq ||
4691+
!phba->sli4_hba.hdwq[i].io_wq) {
4692+
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
4693+
"7777 hdwq's deleted %lx "
4694+
"%lx %x %x\n",
4695+
phba->pport->load_flag,
4696+
phba->hba_flag,
4697+
phba->link_state,
4698+
phba->sli.sli_flag);
4699+
return;
4700+
}
46904701
pring = phba->sli4_hba.hdwq[i].io_wq->pring;
46914702

46924703
spin_lock_irq(&pring->ring_lock);

0 commit comments

Comments
 (0)