Patch "scsi: lpfc: Fix use-after-free KFENCE violation during sysfs firmware write" has been added to the 5.15-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    scsi: lpfc: Fix use-after-free KFENCE violation during sysfs firmware write

to the 5.15-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     scsi-lpfc-fix-use-after-free-kfence-violation-during.patch
and it can be found in the queue-5.15 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit f0da1636ceeaaad1b6bf1e802b168b8020d7e1b1
Author: Justin Tee <justin.tee@xxxxxxxxxxxx>
Date:   Mon Jan 9 15:33:13 2023 -0800

    scsi: lpfc: Fix use-after-free KFENCE violation during sysfs firmware write
    
    [ Upstream commit 21681b81b9ae548c5dae7ae00d931197a27f480c ]
    
    During the sysfs firmware write process, a use-after-free read warning is
    logged from the lpfc_wr_object() routine:
    
      BUG: KFENCE: use-after-free read in lpfc_wr_object+0x235/0x310 [lpfc]
      Use-after-free read at 0x0000000000cf164d (in kfence-#111):
      lpfc_wr_object+0x235/0x310 [lpfc]
      lpfc_write_firmware.cold+0x206/0x30d [lpfc]
      lpfc_sli4_request_firmware_update+0xa6/0x100 [lpfc]
      lpfc_request_firmware_upgrade_store+0x66/0xb0 [lpfc]
      kernfs_fop_write_iter+0x121/0x1b0
      new_sync_write+0x11c/0x1b0
      vfs_write+0x1ef/0x280
      ksys_write+0x5f/0xe0
      do_syscall_64+0x59/0x90
      entry_SYSCALL_64_after_hwframe+0x63/0xcd
    
    The driver accessed wr_object pointer data, which was initialized into
    mailbox payload memory, after the mailbox object was released back to the
    mailbox pool.
    
    Fix by moving the mailbox free calls to the end of the routine ensuring
    that we don't reference internal mailbox memory after release.
    
    Signed-off-by: Justin Tee <justin.tee@xxxxxxxxxxxx>
    Signed-off-by: Martin K. Petersen <martin.petersen@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index df3b190fccd16..7d333167047f5 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -21066,6 +21066,7 @@ lpfc_wr_object(struct lpfc_hba *phba, struct list_head *dmabuf_list,
 	struct lpfc_mbx_wr_object *wr_object;
 	LPFC_MBOXQ_t *mbox;
 	int rc = 0, i = 0;
+	int mbox_status = 0;
 	uint32_t shdr_status, shdr_add_status, shdr_add_status_2;
 	uint32_t shdr_change_status = 0, shdr_csf = 0;
 	uint32_t mbox_tmo;
@@ -21111,11 +21112,15 @@ lpfc_wr_object(struct lpfc_hba *phba, struct list_head *dmabuf_list,
 	wr_object->u.request.bde_count = i;
 	bf_set(lpfc_wr_object_write_length, &wr_object->u.request, written);
 	if (!phba->sli4_hba.intr_enable)
-		rc = lpfc_sli_issue_mbox(phba, mbox, MBX_POLL);
+		mbox_status = lpfc_sli_issue_mbox(phba, mbox, MBX_POLL);
 	else {
 		mbox_tmo = lpfc_mbox_tmo_val(phba, mbox);
-		rc = lpfc_sli_issue_mbox_wait(phba, mbox, mbox_tmo);
+		mbox_status = lpfc_sli_issue_mbox_wait(phba, mbox, mbox_tmo);
 	}
+
+	/* The mbox status needs to be maintained to detect MBOX_TIMEOUT. */
+	rc = mbox_status;
+
 	/* The IOCTL status is embedded in the mailbox subheader. */
 	shdr_status = bf_get(lpfc_mbox_hdr_status,
 			     &wr_object->header.cfg_shdr.response);
@@ -21130,10 +21135,6 @@ lpfc_wr_object(struct lpfc_hba *phba, struct list_head *dmabuf_list,
 				  &wr_object->u.response);
 	}
 
-	if (!phba->sli4_hba.intr_enable)
-		mempool_free(mbox, phba->mbox_mem_pool);
-	else if (rc != MBX_TIMEOUT)
-		mempool_free(mbox, phba->mbox_mem_pool);
 	if (shdr_status || shdr_add_status || shdr_add_status_2 || rc) {
 		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
 				"3025 Write Object mailbox failed with "
@@ -21151,6 +21152,12 @@ lpfc_wr_object(struct lpfc_hba *phba, struct list_head *dmabuf_list,
 		lpfc_log_fw_write_cmpl(phba, shdr_status, shdr_add_status,
 				       shdr_add_status_2, shdr_change_status,
 				       shdr_csf);
+
+	if (!phba->sli4_hba.intr_enable)
+		mempool_free(mbox, phba->mbox_mem_pool);
+	else if (mbox_status != MBX_TIMEOUT)
+		mempool_free(mbox, phba->mbox_mem_pool);
+
 	return rc;
 }
 



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux