Commit 7a33aeda authored by Arun Easi's avatar Arun Easi Committed by Greg Kroah-Hartman

scsi: qla2xxx: Fix unbound NVME response length

commit 00fe717e upstream.

On certain cases when response length is less than 32, NVME response data
is supplied inline in IOCB. This is indicated by some combination of state
flags. There was an instance when a high, and incorrect, response length
was indicated causing driver to overrun buffers. Fix this by checking and
limiting the response payload length.

Fixes: 7401bc18 ("scsi: qla2xxx: Add FC-NVMe command handling")
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/20200124045014.23554-1-hmadhani@marvell.comSigned-off-by: default avatarArun Easi <aeasi@marvell.com>
Signed-off-by: default avatarHimanshu Madhani <hmadhani@marvell.com>
Reviewed-by: default avatarEwan D. Milne <emilne@redhat.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 148c920e
...@@ -2520,12 +2520,6 @@ qla83xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked) ...@@ -2520,12 +2520,6 @@ qla83xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
/* Driver Debug Functions. */ /* Driver Debug Functions. */
/****************************************************************************/ /****************************************************************************/
static inline int
ql_mask_match(uint32_t level)
{
return (level & ql2xextended_error_logging) == level;
}
/* /*
* This function is for formatting and logging debug information. * This function is for formatting and logging debug information.
* It is to be used when vha is available. It formats the message * It is to be used when vha is available. It formats the message
......
...@@ -374,3 +374,9 @@ extern int qla24xx_dump_ram(struct qla_hw_data *, uint32_t, uint32_t *, ...@@ -374,3 +374,9 @@ extern int qla24xx_dump_ram(struct qla_hw_data *, uint32_t, uint32_t *,
extern void qla24xx_pause_risc(struct device_reg_24xx __iomem *, extern void qla24xx_pause_risc(struct device_reg_24xx __iomem *,
struct qla_hw_data *); struct qla_hw_data *);
extern int qla24xx_soft_reset(struct qla_hw_data *); extern int qla24xx_soft_reset(struct qla_hw_data *);
static inline int
ql_mask_match(uint level)
{
return (level & ql2xextended_error_logging) == level;
}
...@@ -1876,6 +1876,18 @@ static void qla24xx_nvme_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, ...@@ -1876,6 +1876,18 @@ static void qla24xx_nvme_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
inbuf = (uint32_t *)&sts->nvme_ersp_data; inbuf = (uint32_t *)&sts->nvme_ersp_data;
outbuf = (uint32_t *)fd->rspaddr; outbuf = (uint32_t *)fd->rspaddr;
iocb->u.nvme.rsp_pyld_len = le16_to_cpu(sts->nvme_rsp_pyld_len); iocb->u.nvme.rsp_pyld_len = le16_to_cpu(sts->nvme_rsp_pyld_len);
if (unlikely(iocb->u.nvme.rsp_pyld_len >
sizeof(struct nvme_fc_ersp_iu))) {
if (ql_mask_match(ql_dbg_io)) {
WARN_ONCE(1, "Unexpected response payload length %u.\n",
iocb->u.nvme.rsp_pyld_len);
ql_log(ql_log_warn, fcport->vha, 0x5100,
"Unexpected response payload length %u.\n",
iocb->u.nvme.rsp_pyld_len);
}
iocb->u.nvme.rsp_pyld_len =
sizeof(struct nvme_fc_ersp_iu);
}
iter = iocb->u.nvme.rsp_pyld_len >> 2; iter = iocb->u.nvme.rsp_pyld_len >> 2;
for (; iter; iter--) for (; iter; iter--)
*outbuf++ = swab32(*inbuf++); *outbuf++ = swab32(*inbuf++);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment