From: Justin Tee justin.tee@broadcom.com
[ Upstream commit 2be1d4f11944cd6283cb97268b3e17c4424945ca ]
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 Signed-off-by: Sasha Levin sashal@kernel.org [Xiangyu: BP to fix CVE: CVE-2024-49891, no test_bit() conflict resolution] Signed-off-by: Xiangyu Chen xiangyu.chen@windriver.com --- drivers/scsi/lpfc/lpfc_hbadisc.c | 3 ++- drivers/scsi/lpfc/lpfc_scsi.c | 13 +++++++++++-- drivers/scsi/lpfc/lpfc_sli.c | 11 +++++++++++ 3 files changed, 24 insertions(+), 3 deletions(-)
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index aaa98a006fdc..d3a5f10b8b83 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -177,7 +177,8 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport) /* Don't schedule a worker thread event if the vport is going down. * The teardown process cleans up the node via lpfc_drop_node. */ - if (vport->load_flag & FC_UNLOADING) { + if ((vport->load_flag & FC_UNLOADING) || + !(phba->hba_flag & HBA_SETUP)) { ((struct lpfc_rport_data *)rport->dd_data)->pnode = NULL; ndlp->rport = NULL;
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 2a81a42de5c1..ed32aa01c711 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -5554,11 +5554,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, + (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 */ diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 587e3c2f7c48..1e04b6fc127a 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -4668,6 +4668,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", + (unsigned long)phba->pport->load_flag, + (unsigned long)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);
From: Justin Tee justin.tee@broadcom.com
[ Upstream commit 2be1d4f11944cd6283cb97268b3e17c4424945ca ]
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 Signed-off-by: Sasha Levin sashal@kernel.org [Xiangyu: BP to fix CVE: CVE-2024-49891, no test_bit() conflict resolution] Signed-off-by: Xiangyu Chen xiangyu.chen@windriver.com --- drivers/scsi/lpfc/lpfc_hbadisc.c | 3 ++- drivers/scsi/lpfc/lpfc_scsi.c | 13 +++++++++++-- drivers/scsi/lpfc/lpfc_sli.c | 11 +++++++++++ 3 files changed, 24 insertions(+), 3 deletions(-)
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 0a01575ab06d..0ad8a10002ce 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -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 (vport->load_flag & FC_UNLOADING) { + if ((vport->load_flag & FC_UNLOADING) || + !(phba->hba_flag & HBA_SETUP)) { spin_lock_irqsave(&ndlp->lock, iflags); ndlp->rport = NULL;
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index cf506556f3b0..070654cc9292 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -5546,11 +5546,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, + (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 */ diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 9cd22588c8eb..9b1ffa84a062 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -4684,6 +4684,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", + (unsigned long)phba->pport->load_flag, + (unsigned long)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);
[ Sasha's backport helper bot ]
Hi,
The upstream commit SHA1 provided is correct: 2be1d4f11944cd6283cb97268b3e17c4424945ca
WARNING: Author mismatch between patch and upstream commit: Backport author: Xiangyu Chen xiangyu.chen@eng.windriver.com Commit author: Justin Tee justin.tee@broadcom.com
Status in newer kernel trees: 6.12.y | Present (exact SHA1) 6.11.y | Present (different SHA1: fd665c8dbdb1) 6.6.y | Not found
Note: The patch differs from the upstream commit: --- --- - 2024-11-27 08:04:07.591042523 -0500 +++ /tmp/tmp.ruHMJiW1bw 2024-11-27 08:04:07.586423956 -0500 @@ -1,3 +1,5 @@ +[ Upstream commit 2be1d4f11944cd6283cb97268b3e17c4424945ca ] + 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 @@ -9,6 +11,9 @@ 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 +Signed-off-by: Sasha Levin sashal@kernel.org +[Xiangyu: BP to fix CVE: CVE-2024-49891, no test_bit() conflict resolution] +Signed-off-by: Xiangyu Chen xiangyu.chen@windriver.com --- drivers/scsi/lpfc/lpfc_hbadisc.c | 3 ++- drivers/scsi/lpfc/lpfc_scsi.c | 13 +++++++++++-- @@ -16,24 +21,24 @@ 3 files changed, 24 insertions(+), 3 deletions(-)
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c -index 6943f6c6395c4..f21c5993e8d72 100644 +index 0a01575ab06d..0ad8a10002ce 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -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)) { +- if (vport->load_flag & FC_UNLOADING) { ++ if ((vport->load_flag & FC_UNLOADING) || ++ !(phba->hba_flag & HBA_SETUP)) { spin_lock_irqsave(&ndlp->lock, iflags); ndlp->rport = NULL;
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c -index 98ce9d97a2257..60cd60ebff38e 100644 +index cf506556f3b0..070654cc9292 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c -@@ -5555,11 +5555,20 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) +@@ -5546,11 +5546,20 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
iocb = &lpfc_cmd->cur_iocbq; if (phba->sli_rev == LPFC_SLI_REV4) { @@ -48,7 +53,7 @@ + "HBA_SETUP %d\n", FAILED, + cmnd->device->id, + (u64)cmnd->device->lun, -+ test_bit(HBA_SETUP, &phba->hba_flag)); ++ (HBA_SETUP & phba->hba_flag)); ret = FAILED; goto out_unlock_hba; } @@ -57,10 +62,10 @@ } /* the command is in process of being cancelled */ diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c -index d240bbded4c8f..332b8d2348e9e 100644 +index 9cd22588c8eb..9b1ffa84a062 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c -@@ -4687,6 +4687,17 @@ lpfc_sli_flush_io_rings(struct lpfc_hba *phba) +@@ -4684,6 +4684,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++) { @@ -69,8 +74,8 @@ + lpfc_printf_log(phba, KERN_ERR, LOG_SLI, + "7777 hdwq's deleted %lx " + "%lx %x %x\n", -+ phba->pport->load_flag, -+ phba->hba_flag, ++ (unsigned long)phba->pport->load_flag, ++ (unsigned long)phba->hba_flag, + phba->link_state, + phba->sli.sli_flag); + return; @@ -78,3 +83,6 @@ pring = phba->sli4_hba.hdwq[i].io_wq->pring;
spin_lock_irq(&pring->ring_lock); +-- +2.25.1 + ---
Results of testing on various branches:
| Branch | Patch Apply | Build Test | |---------------------------|-------------|------------| | stable/linux-6.6.y | Success | Success |
[ Sasha's backport helper bot ]
Hi,
The upstream commit SHA1 provided is correct: 2be1d4f11944cd6283cb97268b3e17c4424945ca
WARNING: Author mismatch between patch and upstream commit: Backport author: Xiangyu Chen xiangyu.chen@eng.windriver.com Commit author: Justin Tee justin.tee@broadcom.com
Status in newer kernel trees: 6.12.y | Present (exact SHA1) 6.11.y | Present (different SHA1: fd665c8dbdb1) 6.6.y | Not found 6.1.y | Not found
Note: The patch differs from the upstream commit: --- --- - 2024-11-27 07:44:21.246175065 -0500 +++ /tmp/tmp.PTEqkEQ2h7 2024-11-27 07:44:21.238682123 -0500 @@ -1,3 +1,5 @@ +[ Upstream commit 2be1d4f11944cd6283cb97268b3e17c4424945ca ] + 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 @@ -9,6 +11,9 @@ 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 +Signed-off-by: Sasha Levin sashal@kernel.org +[Xiangyu: BP to fix CVE: CVE-2024-49891, no test_bit() conflict resolution] +Signed-off-by: Xiangyu Chen xiangyu.chen@windriver.com --- drivers/scsi/lpfc/lpfc_hbadisc.c | 3 ++- drivers/scsi/lpfc/lpfc_scsi.c | 13 +++++++++++-- @@ -16,24 +21,24 @@ 3 files changed, 24 insertions(+), 3 deletions(-)
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c -index 6943f6c6395c4..f21c5993e8d72 100644 +index aaa98a006fdc..d3a5f10b8b83 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c -@@ -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); +@@ -177,7 +177,8 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport) + /* Don't schedule a worker thread event if the vport is going down. + * The teardown process cleans up the node via lpfc_drop_node. + */ +- if (vport->load_flag & FC_UNLOADING) { ++ if ((vport->load_flag & FC_UNLOADING) || ++ !(phba->hba_flag & HBA_SETUP)) { + ((struct lpfc_rport_data *)rport->dd_data)->pnode = NULL; ndlp->rport = NULL;
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c -index 98ce9d97a2257..60cd60ebff38e 100644 +index 2a81a42de5c1..ed32aa01c711 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c -@@ -5555,11 +5555,20 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) +@@ -5554,11 +5554,20 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd)
iocb = &lpfc_cmd->cur_iocbq; if (phba->sli_rev == LPFC_SLI_REV4) { @@ -48,7 +53,7 @@ + "HBA_SETUP %d\n", FAILED, + cmnd->device->id, + (u64)cmnd->device->lun, -+ test_bit(HBA_SETUP, &phba->hba_flag)); ++ (HBA_SETUP & phba->hba_flag)); ret = FAILED; goto out_unlock_hba; } @@ -57,10 +62,10 @@ } /* the command is in process of being cancelled */ diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c -index d240bbded4c8f..332b8d2348e9e 100644 +index 587e3c2f7c48..1e04b6fc127a 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c -@@ -4687,6 +4687,17 @@ lpfc_sli_flush_io_rings(struct lpfc_hba *phba) +@@ -4668,6 +4668,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++) { @@ -69,8 +74,8 @@ + lpfc_printf_log(phba, KERN_ERR, LOG_SLI, + "7777 hdwq's deleted %lx " + "%lx %x %x\n", -+ phba->pport->load_flag, -+ phba->hba_flag, ++ (unsigned long)phba->pport->load_flag, ++ (unsigned long)phba->hba_flag, + phba->link_state, + phba->sli.sli_flag); + return; @@ -78,3 +83,6 @@ pring = phba->sli4_hba.hdwq[i].io_wq->pring;
spin_lock_irq(&pring->ring_lock); +-- +2.25.1 + ---
Results of testing on various branches:
| Branch | Patch Apply | Build Test | |---------------------------|-------------|------------| | stable/linux-6.1.y | Success | Success |
linux-stable-mirror@lists.linaro.org