Skip to content

Commit 51ab4eb

Browse files
Justin Teegregkh
Justin Tee
authored andcommitted
scsi: lpfc: Fix use-after-free KFENCE violation during sysfs firmware write
[ Upstream commit 21681b8 ] 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-torvalds#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 <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent cda2f7e commit 51ab4eb

File tree

1 file changed

+13
-6
lines changed

1 file changed

+13
-6
lines changed

drivers/scsi/lpfc/lpfc_sli.c

+13-6
Original file line numberDiff line numberDiff line change
@@ -21066,6 +21066,7 @@ lpfc_wr_object(struct lpfc_hba *phba, struct list_head *dmabuf_list,
2106621066
struct lpfc_mbx_wr_object *wr_object;
2106721067
LPFC_MBOXQ_t *mbox;
2106821068
int rc = 0, i = 0;
21069+
int mbox_status = 0;
2106921070
uint32_t shdr_status, shdr_add_status, shdr_add_status_2;
2107021071
uint32_t shdr_change_status = 0, shdr_csf = 0;
2107121072
uint32_t mbox_tmo;
@@ -21111,11 +21112,15 @@ lpfc_wr_object(struct lpfc_hba *phba, struct list_head *dmabuf_list,
2111121112
wr_object->u.request.bde_count = i;
2111221113
bf_set(lpfc_wr_object_write_length, &wr_object->u.request, written);
2111321114
if (!phba->sli4_hba.intr_enable)
21114-
rc = lpfc_sli_issue_mbox(phba, mbox, MBX_POLL);
21115+
mbox_status = lpfc_sli_issue_mbox(phba, mbox, MBX_POLL);
2111521116
else {
2111621117
mbox_tmo = lpfc_mbox_tmo_val(phba, mbox);
21117-
rc = lpfc_sli_issue_mbox_wait(phba, mbox, mbox_tmo);
21118+
mbox_status = lpfc_sli_issue_mbox_wait(phba, mbox, mbox_tmo);
2111821119
}
21120+
21121+
/* The mbox status needs to be maintained to detect MBOX_TIMEOUT. */
21122+
rc = mbox_status;
21123+
2111921124
/* The IOCTL status is embedded in the mailbox subheader. */
2112021125
shdr_status = bf_get(lpfc_mbox_hdr_status,
2112121126
&wr_object->header.cfg_shdr.response);
@@ -21130,10 +21135,6 @@ lpfc_wr_object(struct lpfc_hba *phba, struct list_head *dmabuf_list,
2113021135
&wr_object->u.response);
2113121136
}
2113221137

21133-
if (!phba->sli4_hba.intr_enable)
21134-
mempool_free(mbox, phba->mbox_mem_pool);
21135-
else if (rc != MBX_TIMEOUT)
21136-
mempool_free(mbox, phba->mbox_mem_pool);
2113721138
if (shdr_status || shdr_add_status || shdr_add_status_2 || rc) {
2113821139
lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
2113921140
"3025 Write Object mailbox failed with "
@@ -21151,6 +21152,12 @@ lpfc_wr_object(struct lpfc_hba *phba, struct list_head *dmabuf_list,
2115121152
lpfc_log_fw_write_cmpl(phba, shdr_status, shdr_add_status,
2115221153
shdr_add_status_2, shdr_change_status,
2115321154
shdr_csf);
21155+
21156+
if (!phba->sli4_hba.intr_enable)
21157+
mempool_free(mbox, phba->mbox_mem_pool);
21158+
else if (mbox_status != MBX_TIMEOUT)
21159+
mempool_free(mbox, phba->mbox_mem_pool);
21160+
2115421161
return rc;
2115521162
}
2115621163

0 commit comments

Comments
 (0)