Skip to content

Commit 4a8f710

Browse files
logostmartinkpetersen
authored andcommitted
scsi: qla2xxx: Fix unmap of already freed sgl
The sgl is freed in the target stack in target_release_cmd_kref() before calling qlt_free_cmd() but there is an unmap of sgl in qlt_free_cmd() that causes a panic if sgl is not yet DMA unmapped: NIP dma_direct_unmap_sg+0xdc/0x180 LR dma_direct_unmap_sg+0xc8/0x180 Call Trace: ql_dbg_prefix+0x68/0xc0 [qla2xxx] (unreliable) dma_unmap_sg_attrs+0x54/0xf0 qlt_unmap_sg.part.19+0x54/0x1c0 [qla2xxx] qlt_free_cmd+0x124/0x1d0 [qla2xxx] tcm_qla2xxx_release_cmd+0x4c/0xa0 [tcm_qla2xxx] target_put_sess_cmd+0x198/0x370 [target_core_mod] transport_generic_free_cmd+0x6c/0x1b0 [target_core_mod] tcm_qla2xxx_complete_free+0x6c/0x90 [tcm_qla2xxx] The sgl may be left unmapped in error cases of response sending. For instance, qlt_rdy_to_xfer() maps sgl and exits when session is being deleted keeping the sgl mapped. This patch removes use-after-free of the sgl and ensures that the sgl is unmapped for any command that was not sent to firmware. Link: https://lore.kernel.org/r/[email protected] Reviewed-by: Himanshu Madhani <[email protected]> Signed-off-by: Dmitry Bogdanov <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]>
1 parent 7fb223d commit 4a8f710

File tree

1 file changed

+5
-9
lines changed

1 file changed

+5
-9
lines changed

drivers/scsi/qla2xxx/qla_target.c

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3319,8 +3319,7 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type,
33193319
"RESET-RSP online/active/old-count/new-count = %d/%d/%d/%d.\n",
33203320
vha->flags.online, qla2x00_reset_active(vha),
33213321
cmd->reset_count, qpair->chip_reset);
3322-
spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
3323-
return 0;
3322+
goto out_unmap_unlock;
33243323
}
33253324

33263325
/* Does F/W have an IOCBs for this request */
@@ -3445,10 +3444,6 @@ int qlt_rdy_to_xfer(struct qla_tgt_cmd *cmd)
34453444
prm.sg = NULL;
34463445
prm.req_cnt = 1;
34473446

3448-
/* Calculate number of entries and segments required */
3449-
if (qlt_pci_map_calc_cnt(&prm) != 0)
3450-
return -EAGAIN;
3451-
34523447
if (!qpair->fw_started || (cmd->reset_count != qpair->chip_reset) ||
34533448
(cmd->sess && cmd->sess->deleted)) {
34543449
/*
@@ -3466,6 +3461,10 @@ int qlt_rdy_to_xfer(struct qla_tgt_cmd *cmd)
34663461
return 0;
34673462
}
34683463

3464+
/* Calculate number of entries and segments required */
3465+
if (qlt_pci_map_calc_cnt(&prm) != 0)
3466+
return -EAGAIN;
3467+
34693468
spin_lock_irqsave(qpair->qp_lock_ptr, flags);
34703469
/* Does F/W have an IOCBs for this request */
34713470
res = qlt_check_reserve_free_req(qpair, prm.req_cnt);
@@ -3870,9 +3869,6 @@ void qlt_free_cmd(struct qla_tgt_cmd *cmd)
38703869

38713870
BUG_ON(cmd->cmd_in_wq);
38723871

3873-
if (cmd->sg_mapped)
3874-
qlt_unmap_sg(cmd->vha, cmd);
3875-
38763872
if (!cmd->q_full)
38773873
qlt_decr_num_pend_cmds(cmd->vha);
38783874

0 commit comments

Comments
 (0)