Commit 672d1cb4 authored by James Smart's avatar James Smart Committed by Martin K. Petersen
Browse files

scsi: lpfc: Protect memory leak for NPIV ports sending PLOGI_RJT

There is a potential memory leak in lpfc_ignore_els_cmpl() and
lpfc_els_rsp_reject() that was allocated from NPIV PLOGI_RJT
(lpfc_rcv_plogi()'s login_mbox).

Check if cmdiocb->context_un.mbox was allocated in lpfc_ignore_els_cmpl(),
and then free it back to phba->mbox_mem_pool along with mbox->ctx_buf for
service parameters.

For lpfc_els_rsp_reject() failure, free both the ctx_buf for service
parameters and the login_mbox.

Link: https://lore.kernel.org/r/20220412222008.126521-10-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>
parent 577a942d
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -615,8 +615,14 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
		stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
		rc = lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb,
					 ndlp, login_mbox);
		if (rc)
		if (rc) {
			mp = (struct lpfc_dmabuf *)login_mbox->ctx_buf;
			if (mp) {
				lpfc_mbuf_free(phba, mp->virt, mp->phys);
				kfree(mp);
			}
			mempool_free(login_mbox, phba->mbox_mem_pool);
		}
		return 1;
	}

+17 −0
Original line number Diff line number Diff line
@@ -12069,6 +12069,8 @@ lpfc_ignore_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
{
	struct lpfc_nodelist *ndlp = NULL;
	IOCB_t *irsp;
	LPFC_MBOXQ_t *mbox;
	struct lpfc_dmabuf *mp;
	u32 ulp_command, ulp_status, ulp_word4, iotag;
	ulp_command = get_job_cmnd(phba, cmdiocb);
@@ -12080,6 +12082,21 @@ lpfc_ignore_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
	} else {
		irsp = &rspiocb->iocb;
		iotag = irsp->ulpIoTag;
		/* It is possible a PLOGI_RJT for NPIV ports to get aborted.
		 * The MBX_REG_LOGIN64 mbox command is freed back to the
		 * mbox_mem_pool here.
		 */
		if (cmdiocb->context_un.mbox) {
			mbox = cmdiocb->context_un.mbox;
			mp = (struct lpfc_dmabuf *)mbox->ctx_buf;
			if (mp) {
				lpfc_mbuf_free(phba, mp->virt, mp->phys);
				kfree(mp);
			}
			mempool_free(mbox, phba->mbox_mem_pool);
			cmdiocb->context_un.mbox = NULL;
		}
	}
	/* ELS cmd tag <ulpIoTag> completes */