Commit c0abf1a0 authored by James Smart's avatar James Smart Committed by Guo Mengqi
Browse files

scsi: lpfc: Fix null pointer dereference after failing to issue FLOGI and PLOGI

mainline inclusion
from mainline-v5.19-rc1
commit 577a942d
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBP6SH
CVE: CVE-2022-49535

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=577a942df3de2666f6947bdd3a5c9e8d30073424

--------------------------------

[ Upstream commit 577a942d ]

If lpfc_issue_els_flogi() fails and returns non-zero status, the node
reference count is decremented to trigger the release of the nodelist
structure. However, if there is a prior registration or dev-loss-evt work
pending, the node may be released prematurely.  When dev-loss-evt
completes, the released node is referenced causing a use-after-free null
pointer dereference.

Similarly, when processing non-zero ELS PLOGI completion status in
lpfc_cmpl_els_plogi(), the ndlp flags are checked for a transport
registration before triggering node removal.  If dev-loss-evt work is
pending, the node may be released prematurely and a subsequent call to
lpfc_dev_loss_tmo_handler() results in a use after free ndlp dereference.

Add test for pending dev-loss before decrementing the node reference count
for FLOGI, PLOGI, PRLI, and ADISC handling.

Link: https://lore.kernel.org/r/20220412222008.126521-9-jsmart2021@gmail.com


Co-developed-by: default avatarJustin Tee <justin.tee@broadcom.com>
Signed-off-by: default avatarJustin Tee <justin.tee@broadcom.com>
Signed-off-by: default avatarJames Smart <jsmart2021@gmail.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
Conflicts:
	drivers/scsi/lpfc/lpfc_els.c
[Some contexts are not in this version]
Signed-off-by: default avatarGuo Mengqi <guomengqi3@huawei.com>
parent 64f60cf1
Loading
Loading
Loading
Loading
+10 −6
Original line number Diff line number Diff line
@@ -1408,9 +1408,11 @@ lpfc_initial_flogi(struct lpfc_vport *vport)
	}

	if (lpfc_issue_els_flogi(vport, ndlp, 0)) {
		/* This decrement of reference count to node shall kick off
		 * the release of the node.
		/* A node reference should be retained while registered with a
		 * transport or dev-loss-evt work is pending.
		 * Otherwise, decrement node reference to trigger release.
		 */
		if (!(ndlp->nlp_flag & NLP_IN_DEV_LOSS))
			lpfc_nlp_put(ndlp);
		return 0;
	}
@@ -1455,9 +1457,11 @@ lpfc_initial_fdisc(struct lpfc_vport *vport)
	}

	if (lpfc_issue_els_fdisc(vport, ndlp, 0)) {
		/* decrement node reference count to trigger the release of
		 * the node.
		/* A node reference should be retained while registered with a
		 * transport or dev-loss-evt work is pending.
		 * Otherwise, decrement node reference to trigger release.
		 */
		if (!(ndlp->nlp_flag & NLP_IN_DEV_LOSS))
			lpfc_nlp_put(ndlp);
		return 0;
	}