Skip to content

Commit 8bc7c61

Browse files
Justin Teemartinkpetersen
authored andcommitted
scsi: lpfc: Revise lpfc_prep_embed_io routine with proper endian macro usages
On big endian architectures, it is possible to run into a memory out of bounds pointer dereference when FCP targets are zoned. In lpfc_prep_embed_io, the memcpy(ptr, fcp_cmnd, sgl->sge_len) is referencing a little endian formatted sgl->sge_len value. So, the memcpy can cause big endian systems to crash. Redefine the *sgl ptr as a struct sli4_sge_le to make it clear that we are referring to a little endian formatted data structure. And, update the routine with proper le32_to_cpu macro usages. Fixes: af20bb7 ("scsi: lpfc: Add support for 32 byte CDBs") Signed-off-by: Justin Tee <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Martin K. Petersen <[email protected]>
1 parent f65f31a commit 8bc7c61

File tree

1 file changed

+10
-9
lines changed

1 file changed

+10
-9
lines changed

drivers/scsi/lpfc/lpfc_sli.c

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10579,10 +10579,11 @@ lpfc_prep_embed_io(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd)
1057910579
{
1058010580
struct lpfc_iocbq *piocb = &lpfc_cmd->cur_iocbq;
1058110581
union lpfc_wqe128 *wqe = &lpfc_cmd->cur_iocbq.wqe;
10582-
struct sli4_sge *sgl;
10582+
struct sli4_sge_le *sgl;
10583+
u32 type_size;
1058310584

1058410585
/* 128 byte wqe support here */
10585-
sgl = (struct sli4_sge *)lpfc_cmd->dma_sgl;
10586+
sgl = (struct sli4_sge_le *)lpfc_cmd->dma_sgl;
1058610587

1058710588
if (phba->fcp_embed_io) {
1058810589
struct fcp_cmnd *fcp_cmnd;
@@ -10591,9 +10592,9 @@ lpfc_prep_embed_io(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd)
1059110592
fcp_cmnd = lpfc_cmd->fcp_cmnd;
1059210593

1059310594
/* Word 0-2 - FCP_CMND */
10594-
wqe->generic.bde.tus.f.bdeFlags =
10595-
BUFF_TYPE_BDE_IMMED;
10596-
wqe->generic.bde.tus.f.bdeSize = sgl->sge_len;
10595+
type_size = le32_to_cpu(sgl->sge_len);
10596+
type_size |= ULP_BDE64_TYPE_BDE_IMMED;
10597+
wqe->generic.bde.tus.w = type_size;
1059710598
wqe->generic.bde.addrHigh = 0;
1059810599
wqe->generic.bde.addrLow = 72; /* Word 18 */
1059910600

@@ -10602,13 +10603,13 @@ lpfc_prep_embed_io(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd)
1060210603

1060310604
/* Word 18-29 FCP CMND Payload */
1060410605
ptr = &wqe->words[18];
10605-
memcpy(ptr, fcp_cmnd, sgl->sge_len);
10606+
lpfc_sli_pcimem_bcopy(fcp_cmnd, ptr, le32_to_cpu(sgl->sge_len));
1060610607
} else {
1060710608
/* Word 0-2 - Inline BDE */
1060810609
wqe->generic.bde.tus.f.bdeFlags = BUFF_TYPE_BDE_64;
10609-
wqe->generic.bde.tus.f.bdeSize = sgl->sge_len;
10610-
wqe->generic.bde.addrHigh = sgl->addr_hi;
10611-
wqe->generic.bde.addrLow = sgl->addr_lo;
10610+
wqe->generic.bde.tus.f.bdeSize = le32_to_cpu(sgl->sge_len);
10611+
wqe->generic.bde.addrHigh = le32_to_cpu(sgl->addr_hi);
10612+
wqe->generic.bde.addrLow = le32_to_cpu(sgl->addr_lo);
1061210613

1061310614
/* Word 10 */
1061410615
bf_set(wqe_dbde, &wqe->generic.wqe_com, 1);

0 commit comments

Comments
 (0)