From: yuuzheng <yuuzh...@google.com>

[ Upstream commit 1f889b58716a5f5e3e4fe0e6742c1a4472f29ac1 ]

A use-after-free or null-pointer error occurs when the 251-byte response
data is copied from IOMB buffer to response message buffer in function
pm8001_mpi_get_nvmd_resp().

After sending the command get_nvmd_data(), the caller begins to sleep by
calling wait_for_complete() and waits for the wake-up from calling
complete() in pm8001_mpi_get_nvmd_resp(). Due to unexpected events (e.g.,
interrupt), if response buffer gets freed before memcpy(), a use-after-free
error will occur. To fix this, the complete() should be called after
memcpy().

Link: 
https://lore.kernel.org/r/20201102165528.26510-5-viswa...@microchip.com.com
Acked-by: Jack Wang <jinpu.w...@cloud.ionos.com>
Signed-off-by: yuuzheng <yuuzh...@google.com>
Signed-off-by: Viswas G <viswa...@microchip.com>
Signed-off-by: Ruksar Devadi <ruksar.dev...@microchip.com>
Signed-off-by: Radha Ramachandran <ra...@google.com>
Signed-off-by: Martin K. Petersen <martin.peter...@oracle.com>
Signed-off-by: Sasha Levin <sas...@kernel.org>
---
 drivers/scsi/pm8001/pm8001_hwi.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
index f8e11f672d1e2..f6d4a7578c80f 100644
--- a/drivers/scsi/pm8001/pm8001_hwi.c
+++ b/drivers/scsi/pm8001/pm8001_hwi.c
@@ -3232,10 +3232,15 @@ pm8001_mpi_get_nvmd_resp(struct pm8001_hba_info 
*pm8001_ha, void *piomb)
                pm8001_ha->memoryMap.region[NVMD].virt_ptr,
                fw_control_context->len);
        kfree(ccb->fw_control_context);
+       /* To avoid race condition, complete should be
+        * called after the message is copied to
+        * fw_control_context->usrAddr
+        */
+       complete(pm8001_ha->nvmd_completion);
+       PM8001_MSG_DBG(pm8001_ha, pm8001_printk("Set nvm data complete!\n"));
        ccb->task = NULL;
        ccb->ccb_tag = 0xFFFFFFFF;
        pm8001_tag_free(pm8001_ha, tag);
-       complete(pm8001_ha->nvmd_completion);
 }
 
 int pm8001_mpi_local_phy_ctl(struct pm8001_hba_info *pm8001_ha, void *piomb)
-- 
2.27.0

Reply via email to