mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 06:01:57 +00:00
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 <justin.tee@broadcom.com> Link: https://lore.kernel.org/r/20240726231512.92867-4-justintee8345@gmail.com Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
f1bfe32073
commit
2be1d4f119
@ -175,7 +175,8 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
|
||||
ndlp->nlp_state, ndlp->fc4_xpt_flags);
|
||||
|
||||
/* Don't schedule a worker thread event if the vport is going down. */
|
||||
if (test_bit(FC_UNLOADING, &vport->load_flag)) {
|
||||
if (test_bit(FC_UNLOADING, &vport->load_flag) ||
|
||||
!test_bit(HBA_SETUP, &phba->hba_flag)) {
|
||||
spin_lock_irqsave(&ndlp->lock, iflags);
|
||||
ndlp->rport = NULL;
|
||||
|
||||
|
@ -5555,11 +5555,20 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
|
||||
|
||||
iocb = &lpfc_cmd->cur_iocbq;
|
||||
if (phba->sli_rev == LPFC_SLI_REV4) {
|
||||
pring_s4 = phba->sli4_hba.hdwq[iocb->hba_wqidx].io_wq->pring;
|
||||
if (!pring_s4) {
|
||||
/* if the io_wq & pring are gone, the port was reset. */
|
||||
if (!phba->sli4_hba.hdwq[iocb->hba_wqidx].io_wq ||
|
||||
!phba->sli4_hba.hdwq[iocb->hba_wqidx].io_wq->pring) {
|
||||
lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP,
|
||||
"2877 SCSI Layer I/O Abort Request "
|
||||
"IO CMPL Status x%x ID %d LUN %llu "
|
||||
"HBA_SETUP %d\n", FAILED,
|
||||
cmnd->device->id,
|
||||
(u64)cmnd->device->lun,
|
||||
test_bit(HBA_SETUP, &phba->hba_flag));
|
||||
ret = FAILED;
|
||||
goto out_unlock_hba;
|
||||
}
|
||||
pring_s4 = phba->sli4_hba.hdwq[iocb->hba_wqidx].io_wq->pring;
|
||||
spin_lock(&pring_s4->ring_lock);
|
||||
}
|
||||
/* the command is in process of being cancelled */
|
||||
|
@ -4687,6 +4687,17 @@ lpfc_sli_flush_io_rings(struct lpfc_hba *phba)
|
||||
/* Look on all the FCP Rings for the iotag */
|
||||
if (phba->sli_rev >= LPFC_SLI_REV4) {
|
||||
for (i = 0; i < phba->cfg_hdw_queue; i++) {
|
||||
if (!phba->sli4_hba.hdwq ||
|
||||
!phba->sli4_hba.hdwq[i].io_wq) {
|
||||
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
|
||||
"7777 hdwq's deleted %lx "
|
||||
"%lx %x %x\n",
|
||||
phba->pport->load_flag,
|
||||
phba->hba_flag,
|
||||
phba->link_state,
|
||||
phba->sli.sli_flag);
|
||||
return;
|
||||
}
|
||||
pring = phba->sli4_hba.hdwq[i].io_wq->pring;
|
||||
|
||||
spin_lock_irq(&pring->ring_lock);
|
||||
|
Loading…
Reference in New Issue
Block a user