Commit 69a3a7bc authored by James Smart's avatar James Smart Committed by Martin K. Petersen
Browse files

scsi: lpfc: Fix memory overwrite during FC-GS I/O abort handling

When an FC-GS I/O is aborted by lpfc, the driver requires a node pointer
for a dereference operation.  In the abort I/O routine, the driver miscasts
a context pointer to the wrong data type and overwrites a single byte
outside of the allocated space.  This miscast is done in the abort I/O
function handler because the handler works on both FC-GS and FC-LS
commands. However, the code neglected to get the correct job location for
the node.

Fix this by acquiring the necessary node pointer from the correct job
structure depending on the I/O type.

Link: https://lore.kernel.org/r/20211004231210.35524-1-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 a013c71c
Loading
Loading
Loading
Loading
+7 −4
Original line number Diff line number Diff line
@@ -12292,12 +12292,12 @@ void
lpfc_ignore_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
		     struct lpfc_iocbq *rspiocb)
{
	struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
	struct lpfc_nodelist *ndlp = NULL;
	IOCB_t *irsp = &rspiocb->iocb;
	/* ELS cmd tag <ulpIoTag> completes */
	lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
			"0139 Ignoring ELS cmd tag x%x completion Data: "
			"0139 Ignoring ELS cmd code x%x completion Data: "
			"x%x x%x x%x\n",
			irsp->ulpIoTag, irsp->ulpStatus,
			irsp->un.ulpWord[4], irsp->ulpTimeout);
@@ -12305,10 +12305,13 @@ lpfc_ignore_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
	 * Deref the ndlp after free_iocb. sli_release_iocb will access the ndlp
	 * if exchange is busy.
	 */
	if (cmdiocb->iocb.ulpCommand == CMD_GEN_REQUEST64_CR)
	if (cmdiocb->iocb.ulpCommand == CMD_GEN_REQUEST64_CR) {
		ndlp = cmdiocb->context_un.ndlp;
		lpfc_ct_free_iocb(phba, cmdiocb);
	else
	} else {
		ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
		lpfc_els_free_iocb(phba, cmdiocb);
	}
	lpfc_nlp_put(ndlp);
}