Message ID | 20210421234511.102206-1-jsmart2021@gmail.com |
---|---|
State | New |
Headers | show |
Series | [REPOST] lpfc: Fix bad memory access during VPD DUMP mailbox command | expand |
On Wed, 21 Apr 2021 16:45:11 -0700, James Smart wrote: > The dump command for reading a region passes a requested read length > specified in words (4byte units). The response overwrites the same > field with the actual number of bytes read. > > The mailbox handler for DUMP which reads VPD data (region 23) is > treating the response field as if it were still a word_cnt, thus > multiplying it by 4 to set the read's "length". Given the read value > was calculated based on the size of the read buffer, the longer > response length runs off the end of the buffer. > > [...] Applied to 5.13/scsi-fixes, thanks! [1/1] lpfc: Fix bad memory access during VPD DUMP mailbox command https://git.kernel.org/mkp/scsi/c/e4ec10228fdf -- Martin K. Petersen Oracle Linux Engineering
On Wed, 21 Apr 2021 16:45:11 -0700, James Smart wrote: > The dump command for reading a region passes a requested read length > specified in words (4byte units). The response overwrites the same > field with the actual number of bytes read. > > The mailbox handler for DUMP which reads VPD data (region 23) is > treating the response field as if it were still a word_cnt, thus > multiplying it by 4 to set the read's "length". Given the read value > was calculated based on the size of the read buffer, the longer > response length runs off the end of the buffer. > > [...] Applied to 5.13/scsi-fixes, thanks! [1/1] lpfc: Fix bad memory access during VPD DUMP mailbox command https://git.kernel.org/mkp/scsi/c/e4ec10228fdf -- Martin K. Petersen Oracle Linux Engineering
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 1e4c792bb660..5f018d02bf56 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -254,13 +254,13 @@ lpfc_config_port_prep(struct lpfc_hba *phba) if (mb->un.varDmp.word_cnt == 0) break; - i = mb->un.varDmp.word_cnt * sizeof(uint32_t); - if (offset + i > DMP_VPD_SIZE) - i = DMP_VPD_SIZE - offset; + if (mb->un.varDmp.word_cnt > DMP_VPD_SIZE - offset) + mb->un.varDmp.word_cnt = DMP_VPD_SIZE - offset; lpfc_sli_pcimem_bcopy(((uint8_t *)mb) + DMP_RSP_OFFSET, - lpfc_vpd_data + offset, i); - offset += i; - } while (offset < DMP_VPD_SIZE); + lpfc_vpd_data + offset, + mb->un.varDmp.word_cnt); + offset += mb->un.varDmp.word_cnt; + } while (mb->un.varDmp.word_cnt && offset < DMP_VPD_SIZE); lpfc_parse_vpd(phba, lpfc_vpd_data, offset); diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 579ac75dfe79..573c8599d71c 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -19777,7 +19777,7 @@ lpfc_sli_get_config_region23(struct lpfc_hba *phba, char *rgn23_data) LPFC_MBOXQ_t *pmb = NULL; MAILBOX_t *mb; uint32_t offset = 0; - int i, rc; + int rc; if (!rgn23_data) return 0; @@ -19808,13 +19808,14 @@ lpfc_sli_get_config_region23(struct lpfc_hba *phba, char *rgn23_data) if (mb->un.varDmp.word_cnt == 0) break; - i = mb->un.varDmp.word_cnt * sizeof(uint32_t); - if (offset + i > DMP_RGN23_SIZE) - i = DMP_RGN23_SIZE - offset; + if (mb->un.varDmp.word_cnt > DMP_RGN23_SIZE - offset) + mb->un.varDmp.word_cnt = DMP_RGN23_SIZE - offset; + lpfc_sli_pcimem_bcopy(((uint8_t *)mb) + DMP_RSP_OFFSET, - rgn23_data + offset, i); - offset += i; - } while (offset < DMP_RGN23_SIZE); + rgn23_data + offset, + mb->un.varDmp.word_cnt); + offset += mb->un.varDmp.word_cnt; + } while (mb->un.varDmp.word_cnt && offset < DMP_RGN23_SIZE); mempool_free(pmb, phba->mbox_mem_pool); return offset;