The Linux Kernel Mailing List
 help / color / mirror / Atom feed
From: Michael Bommarito <michael.bommarito@gmail.com>
To: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>,
	"Martin K. Petersen" <martin.petersen@oracle.com>,
	Justin Tee <justin.tee@broadcom.com>
Cc: Paul Ely <paul.ely@broadcom.com>,
	James Smart <jsmart2021@gmail.com>,
	linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org,
	stable@vger.kernel.org
Subject: [PATCH 2/2] scsi: lpfc: add KUnit coverage for EDC descriptor bounds
Date: Thu,  9 Jul 2026 22:29:32 -0400	[thread overview]
Message-ID: <20260710022932.3741311-3-michael.bommarito@gmail.com> (raw)
In-Reply-To: <20260710022932.3741311-1-michael.bommarito@gmail.com>

Add KUnit coverage for lpfc_els_rcv_edc() descriptor-list bounds. The
tests live in lpfc_els.c so they can drive the real static EDC parser
without exporting test-only symbols.

The suite covers a valid congestion-signaling EDC descriptor and a
malformed EDC payload whose top-level descriptor-list length exceeds the
received payload. That malformed case documents the frame rejected by
the previous patch.

Assisted-by: Codex:gpt-5-5-xhigh
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
---
 drivers/scsi/Kconfig         |   7 ++
 drivers/scsi/lpfc/lpfc_els.c | 154 +++++++++++++++++++++++++++++++++++
 2 files changed, 161 insertions(+)

diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 19d0884479a24..e0f01ddd22707 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -1163,6 +1163,13 @@ config SCSI_LPFC_DEBUG_FS
 	  This makes debugging information from the lpfc driver
 	  available via the debugfs filesystem.
 
+config LPFC_EDC_KUNIT_TEST
+	bool "KUnit tests for lpfc EDC descriptor bounds" if !KUNIT_ALL_TESTS
+	depends on KUNIT && SCSI_LPFC
+	default KUNIT_ALL_TESTS
+	help
+	  Internal validation coverage for lpfc EDC descriptor list bounds.
+
 source "drivers/scsi/elx/Kconfig"
 
 config SCSI_SIM710
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 5408b116f2d5a..0711f88da3f1a 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -12574,3 +12574,157 @@ lpfc_cmpl_els_uvem(struct lpfc_hba *phba, struct lpfc_iocbq *icmdiocb,
 	lpfc_els_free_iocb(phba, icmdiocb);
 	lpfc_nlp_put(ndlp);
 }
+
+#if IS_ENABLED(CONFIG_LPFC_EDC_KUNIT_TEST)
+#include <kunit/device.h>
+#include <kunit/test.h>
+
+static void lpfc_edc_kunit_prep_stub(struct lpfc_iocbq *cmdiocbq,
+				     struct lpfc_vport *vport,
+				     struct lpfc_dmabuf *bmp, u16 cmd_size,
+				     u32 did, u32 elscmd, u8 tmo,
+				     u8 expect_rsp)
+{
+}
+
+static void lpfc_edc_kunit_release_stub(struct lpfc_hba *phba,
+					struct lpfc_iocbq *iocbq)
+{
+}
+
+static int lpfc_edc_kunit_issue_mbox_stub(struct lpfc_hba *phba,
+					  LPFC_MBOXQ_t *mboxq,
+					  uint32_t flag)
+{
+	mempool_free(mboxq, phba->mbox_mem_pool);
+	return 0;
+}
+
+static void lpfc_edc_kunit_setup_hba(struct kunit *test,
+				     struct lpfc_hba *phba,
+				     struct lpfc_vport *vport)
+{
+	struct lpfc_iocbq *free_iocbs;
+	struct device *kdev;
+	int i;
+
+	spin_lock_init(&phba->hbalock);
+	INIT_LIST_HEAD(&phba->lpfc_iocb_list);
+	INIT_LIST_HEAD(&phba->elsbuf);
+	phba->link_state = LPFC_LINK_DOWN;
+	phba->sli_rev = LPFC_SLI_REV3;
+	phba->__lpfc_sli_prep_els_req_rsp = lpfc_edc_kunit_prep_stub;
+	phba->__lpfc_sli_release_iocbq = lpfc_edc_kunit_release_stub;
+	phba->lpfc_sli_issue_mbox = lpfc_edc_kunit_issue_mbox_stub;
+	phba->pport = vport;
+
+	free_iocbs = kunit_kzalloc(test, 4 * sizeof(*free_iocbs), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_NULL(test, free_iocbs);
+	for (i = 0; i < 4; i++)
+		list_add_tail(&free_iocbs[i].list, &phba->lpfc_iocb_list);
+
+	kdev = kunit_device_register(test, "lpfc_edc_test");
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, kdev);
+	phba->lpfc_mbuf_pool = dma_pool_create("lpfc_edc_mbuf", kdev,
+					       LPFC_BPL_SIZE, 8, 0);
+	KUNIT_ASSERT_NOT_NULL(test, phba->lpfc_mbuf_pool);
+	phba->mbox_mem_pool = mempool_create_kmalloc_pool(1,
+							  sizeof(LPFC_MBOXQ_t));
+	KUNIT_ASSERT_NOT_NULL(test, phba->mbox_mem_pool);
+}
+
+static void lpfc_edc_kunit_teardown_hba(struct lpfc_hba *phba)
+{
+	if (phba->mbox_mem_pool)
+		mempool_destroy(phba->mbox_mem_pool);
+	if (phba->lpfc_mbuf_pool)
+		dma_pool_destroy(phba->lpfc_mbuf_pool);
+}
+
+static void lpfc_edc_kunit_run(struct kunit *test, bool malformed)
+{
+	struct lpfc_hba *phba;
+	struct lpfc_vport *vport;
+	struct lpfc_nodelist *ndlp;
+	struct lpfc_iocbq *cmdiocb;
+	struct lpfc_dmabuf *cmd_dmabuf;
+	struct fc_els_edc *edc;
+	struct fc_tlv_desc *tlv;
+	size_t payload_len;
+
+	phba = kunit_kzalloc(test, sizeof(*phba), GFP_KERNEL);
+	vport = kunit_kzalloc(test, sizeof(*vport), GFP_KERNEL);
+	ndlp = kunit_kzalloc(test, sizeof(*ndlp), GFP_KERNEL);
+	cmdiocb = kunit_kzalloc(test, sizeof(*cmdiocb), GFP_KERNEL);
+	cmd_dmabuf = kunit_kzalloc(test, sizeof(*cmd_dmabuf), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_NULL(test, phba);
+	KUNIT_ASSERT_NOT_NULL(test, vport);
+	KUNIT_ASSERT_NOT_NULL(test, ndlp);
+	KUNIT_ASSERT_NOT_NULL(test, cmdiocb);
+	KUNIT_ASSERT_NOT_NULL(test, cmd_dmabuf);
+
+	vport->phba = phba;
+	ndlp->nlp_DID = Fabric_Cntl_DID;
+	lpfc_edc_kunit_setup_hba(test, phba, vport);
+
+	if (malformed)
+		payload_len = sizeof(*edc) + FC_TLV_DESC_HDR_SZ;
+	else
+		payload_len = sizeof(*edc) +
+			      sizeof(struct fc_diag_cg_sig_desc);
+
+	cmd_dmabuf->virt = kunit_kzalloc(test, payload_len, GFP_KERNEL);
+	KUNIT_ASSERT_NOT_NULL(test, cmd_dmabuf->virt);
+	INIT_LIST_HEAD(&cmd_dmabuf->list);
+
+	edc = cmd_dmabuf->virt;
+	edc->edc_cmd = ELS_EDC;
+	tlv = edc->desc;
+	if (malformed) {
+		edc->desc_len = cpu_to_be32(0x100);
+		tlv->desc_tag = cpu_to_be32(0xdeadbeef);
+		tlv->desc_len = cpu_to_be32(0);
+	} else {
+		struct fc_diag_cg_sig_desc *cgn = (void *)tlv;
+
+		edc->desc_len = cpu_to_be32(sizeof(*cgn));
+		cgn->desc_tag = cpu_to_be32(ELS_DTAG_CG_SIGNAL_CAP);
+		cgn->desc_len =
+			cpu_to_be32(FC_TLV_DESC_LENGTH_FROM_SZ(*cgn));
+		cgn->xmt_signal_capability =
+			cpu_to_be32(EDC_CG_SIG_NOTSUPPORTED);
+		cgn->xmt_signal_frequency.count =
+			cpu_to_be16(EDC_CG_SIGFREQ_CNT_MIN);
+		cgn->xmt_signal_frequency.units =
+			cpu_to_be16(EDC_CG_SIGFREQ_MSEC);
+	}
+
+	cmdiocb->cmd_dmabuf = cmd_dmabuf;
+	lpfc_els_rcv_edc(vport, cmdiocb, ndlp, payload_len);
+
+	KUNIT_EXPECT_TRUE(test, true);
+	lpfc_edc_kunit_teardown_hba(phba);
+}
+
+static void lpfc_edc_control_test(struct kunit *test)
+{
+	lpfc_edc_kunit_run(test, false);
+}
+
+static void lpfc_edc_oob_test(struct kunit *test)
+{
+	lpfc_edc_kunit_run(test, true);
+}
+
+static struct kunit_case lpfc_edc_test_cases[] = {
+	KUNIT_CASE(lpfc_edc_control_test),
+	KUNIT_CASE(lpfc_edc_oob_test),
+	{}
+};
+
+static struct kunit_suite lpfc_edc_test_suite = {
+	.name = "lpfc_edc",
+	.test_cases = lpfc_edc_test_cases,
+};
+kunit_test_suite(lpfc_edc_test_suite);
+#endif /* CONFIG_LPFC_EDC_KUNIT_TEST */

  parent reply	other threads:[~2026-07-10  2:29 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-10  2:29 [PATCH 0/2] scsi: lpfc: bound EDC descriptor TLV walk Michael Bommarito
2026-07-10  2:29 ` [PATCH 1/2] scsi: lpfc: bound EDC descriptor list by payload length Michael Bommarito
2026-07-10  2:29 ` Michael Bommarito [this message]
2026-07-10 16:53 ` [PATCH 0/2] scsi: lpfc: bound EDC descriptor TLV walk Justin Tee

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260710022932.3741311-3-michael.bommarito@gmail.com \
    --to=michael.bommarito@gmail.com \
    --cc=James.Bottomley@HansenPartnership.com \
    --cc=jsmart2021@gmail.com \
    --cc=justin.tee@broadcom.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-scsi@vger.kernel.org \
    --cc=martin.petersen@oracle.com \
    --cc=paul.ely@broadcom.com \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox