Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

pm8001: fix a memory leak in flash_update

ccb->fw_control_context is copied to local fw_control_context and
the local variable is never used later

Free ccb->fw_control_context. The task is forgotten thus also the
reference to fw_control_context and the completion thread takes the info
from virt_ptr again.

Signed-off-by: Tomas Henzl <thenzl@redhat.com>
Acked-by: Suresh Thiagarajan <Suresh.Thiagarajan@pmcs.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>

authored by

Tomas Henzl and committed by
Christoph Hellwig
9422e864 da225498

+6 -6
+6 -6
drivers/scsi/pm8001/pm8001_hwi.c
··· 3624 3624 void *piomb) 3625 3625 { 3626 3626 u32 status; 3627 - struct fw_control_ex fw_control_context; 3628 3627 struct fw_flash_Update_resp *ppayload = 3629 3628 (struct fw_flash_Update_resp *)(piomb + 4); 3630 3629 u32 tag = le32_to_cpu(ppayload->tag); 3631 3630 struct pm8001_ccb_info *ccb = &pm8001_ha->ccb_info[tag]; 3632 3631 status = le32_to_cpu(ppayload->status); 3633 - memcpy(&fw_control_context, 3634 - ccb->fw_control_context, 3635 - sizeof(fw_control_context)); 3636 3632 switch (status) { 3637 3633 case FLASH_UPDATE_COMPLETE_PENDING_REBOOT: 3638 3634 PM8001_MSG_DBG(pm8001_ha, ··· 3671 3675 pm8001_printk("No matched status = %d\n", status)); 3672 3676 break; 3673 3677 } 3674 - ccb->fw_control_context->fw_control->retcode = status; 3675 - complete(pm8001_ha->nvmd_completion); 3678 + kfree(ccb->fw_control_context); 3676 3679 ccb->task = NULL; 3677 3680 ccb->ccb_tag = 0xFFFFFFFF; 3678 3681 pm8001_tag_free(pm8001_ha, tag); 3682 + complete(pm8001_ha->nvmd_completion); 3679 3683 return 0; 3680 3684 } 3681 3685 ··· 4880 4884 break; 4881 4885 } 4882 4886 rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &nvmd_req, 0); 4887 + if (rc) { 4888 + kfree(fw_control_context); 4889 + pm8001_tag_free(pm8001_ha, tag); 4890 + } 4883 4891 return rc; 4884 4892 } 4885 4893