From 724f6b43a3492b02e2ebc88f9fb749d1405098e2 Mon Sep 17 00:00:00 2001 From: James Smart Date: Sun, 11 Apr 2021 18:31:18 -0700 Subject: scsi: lpfc: Fix use-after-free on unused nodes after port swap During target port swap, the swap logic ignores the DROPPED flag in the nodes. As a node then moves into the UNUSED state, the reference count will be dropped. If a node is later reused and moved out of the UNUSED state, an access can result in a use-after-free assert. Fix by having the port swap logic propagate the DROPPED flag when switching nodes. This will avoid reference from being dropped. Link: https://lore.kernel.org/r/20210412013127.2387-8-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_els.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'drivers/scsi') diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index ed57d92e96e1..c919bedd931c 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -1691,6 +1691,15 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp, else new_ndlp->nlp_flag &= ~NLP_RPI_REGISTERED; + /* + * Retain the DROPPED flag. This will take care of the init + * refcount when affecting the state change + */ + if (keep_new_nlp_flag & NLP_DROPPED) + new_ndlp->nlp_flag |= NLP_DROPPED; + else + new_ndlp->nlp_flag &= ~NLP_DROPPED; + ndlp->nlp_flag = keep_new_nlp_flag; /* if ndlp had NLP_UNREG_INP set, keep it */ @@ -1705,6 +1714,15 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp, else ndlp->nlp_flag &= ~NLP_RPI_REGISTERED; + /* + * Retain the DROPPED flag. This will take care of the init + * refcount when affecting the state change + */ + if (keep_nlp_flag & NLP_DROPPED) + ndlp->nlp_flag |= NLP_DROPPED; + else + ndlp->nlp_flag &= ~NLP_DROPPED; + spin_unlock_irq(&new_ndlp->lock); spin_unlock_irq(&ndlp->lock); -- cgit v1.2.3