Skip to content

Commit

Permalink
scsi: qla2xxx: Fix use-after-free issues in qla2xxx_qpair_sp_free_dma()
Browse files Browse the repository at this point in the history
The current order for freeing memory is as follows:
- struct crc_context itself.
- struct crc_context member pointers.

Change the freeing order into the following:
- struct crc_context member pointers.
- struct crc_context itself.

Detected by Coverity.

Cc: Himanshu Madhani <[email protected]>
Cc: Giridhar Malavali <[email protected]>
Fixes: 50b8127 ("scsi: qla2xxx: Fix DMA error when the DIF sg buffer crosses 4GB boundary") # v5.1-rc1.
Fixes: d745952 ("scsi: qla2xxx: Add multiple queue pair functionality.") # v4.10.
Signed-off-by: Bart Van Assche <[email protected]>
Acked-by: Himanshu Madhani <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
  • Loading branch information
bvanassche authored and martinkpetersen committed Apr 29, 2019
1 parent 24afabd commit d8f945b
Showing 1 changed file with 20 additions and 18 deletions.
38 changes: 20 additions & 18 deletions drivers/scsi/qla2xxx/qla_os.c
Original file line number Diff line number Diff line change
Expand Up @@ -764,25 +764,8 @@ qla2xxx_qpair_sp_free_dma(void *ptr)
sp->flags &= ~SRB_CRC_CTX_DSD_VALID;
}

if (sp->flags & SRB_CRC_CTX_DMA_VALID) {
struct crc_context *ctx0 = ctx;

dma_pool_free(ha->dl_dma_pool, ctx, ctx0->crc_ctx_dma);
sp->flags &= ~SRB_CRC_CTX_DMA_VALID;
}

if (sp->flags & SRB_FCP_CMND_DMA_VALID) {
struct ct6_dsd *ctx1 = ctx;
dma_pool_free(ha->fcp_cmnd_dma_pool, ctx1->fcp_cmnd,
ctx1->fcp_cmnd_dma);
list_splice(&ctx1->dsd_list, &ha->gbl_dsd_list);
ha->gbl_dsd_inuse -= ctx1->dsd_use_cnt;
ha->gbl_dsd_avail += ctx1->dsd_use_cnt;
mempool_free(ctx1, ha->ctx_mempool);
sp->flags &= ~SRB_FCP_CMND_DMA_VALID;
}
if (sp->flags & SRB_DIF_BUNDL_DMA_VALID) {
struct crc_context *difctx = sp->u.scmd.ctx;
struct crc_context *difctx = ctx;
struct dsd_dma *dif_dsd, *nxt_dsd;

list_for_each_entry_safe(dif_dsd, nxt_dsd,
Expand Down Expand Up @@ -816,6 +799,25 @@ qla2xxx_qpair_sp_free_dma(void *ptr)
}
sp->flags &= ~SRB_DIF_BUNDL_DMA_VALID;
}

if (sp->flags & SRB_FCP_CMND_DMA_VALID) {
struct ct6_dsd *ctx1 = ctx;

dma_pool_free(ha->fcp_cmnd_dma_pool, ctx1->fcp_cmnd,
ctx1->fcp_cmnd_dma);
list_splice(&ctx1->dsd_list, &ha->gbl_dsd_list);
ha->gbl_dsd_inuse -= ctx1->dsd_use_cnt;
ha->gbl_dsd_avail += ctx1->dsd_use_cnt;
mempool_free(ctx1, ha->ctx_mempool);
sp->flags &= ~SRB_FCP_CMND_DMA_VALID;
}

if (sp->flags & SRB_CRC_CTX_DMA_VALID) {
struct crc_context *ctx0 = ctx;

dma_pool_free(ha->dl_dma_pool, ctx, ctx0->crc_ctx_dma);
sp->flags &= ~SRB_CRC_CTX_DMA_VALID;
}
}

void
Expand Down

0 comments on commit d8f945b

Please sign in to comment.