From e749fa9c2701b143fd778a8e7cd083b92d10d1ef Mon Sep 17 00:00:00 2001 From: Ziv Hirsch Date: Mon, 11 Apr 2022 12:31:02 +0300 Subject: [PATCH] nvmf: fix buffer overflow on admin commands When req->iovcnt is bigger than 1, `memset(req->data, 0, req->length)` is wrong. Signed-off-by: Ziv Hirsch Change-Id: Ie53eba686b4c5889bbde3b3644d51acbef303b42 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/12216 Community-CI: Broadcom CI Community-CI: Mellanox Build Bot Tested-by: SPDK CI Jenkins Reviewed-by: Jim Harris Reviewed-by: Aleksey Marchuk Reviewed-by: Tomasz Zawadzki --- lib/nvmf/ctrlr.c | 20 ++++++++++++-------- test/unit/lib/nvmf/ctrlr.c/ctrlr_ut.c | 3 +++ 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/lib/nvmf/ctrlr.c b/lib/nvmf/ctrlr.c index 7dc8d0095..d9d752f4c 100644 --- a/lib/nvmf/ctrlr.c +++ b/lib/nvmf/ctrlr.c @@ -2032,21 +2032,25 @@ struct copy_iovs_ctx { }; static void -_init_copy_iovs_ctx(struct copy_iovs_ctx *copy_ctx, struct iovec *iovs, int iovcnt) +_clear_iovs(struct iovec *iovs, int iovcnt) { int iov_idx = 0; struct iovec *iov; + while (iov_idx < iovcnt) { + iov = &iovs[iov_idx]; + memset(iov->iov_base, 0, iov->iov_len); + iov_idx++; + } +} + +static void +_init_copy_iovs_ctx(struct copy_iovs_ctx *copy_ctx, struct iovec *iovs, int iovcnt) +{ copy_ctx->iovs = iovs; copy_ctx->iovcnt = iovcnt; copy_ctx->cur_iov_idx = 0; copy_ctx->cur_iov_offset = 0; - - while (iov_idx < copy_ctx->iovcnt) { - iov = ©_ctx->iovs[iov_idx]; - memset(iov->iov_base, 0, iov->iov_len); - iov_idx++; - } } static size_t @@ -3324,7 +3328,7 @@ nvmf_ctrlr_process_admin_cmd(struct spdk_nvmf_request *req) } if (req->data && spdk_nvme_opc_get_data_transfer(cmd->opc) == SPDK_NVME_DATA_CONTROLLER_TO_HOST) { - memset(req->data, 0, req->length); + _clear_iovs(req->iov, req->iovcnt); } if (ctrlr->subsys->subtype == SPDK_NVMF_SUBTYPE_DISCOVERY) { diff --git a/test/unit/lib/nvmf/ctrlr.c/ctrlr_ut.c b/test/unit/lib/nvmf/ctrlr.c/ctrlr_ut.c index abaf4e363..1429a7960 100644 --- a/test/unit/lib/nvmf/ctrlr.c/ctrlr_ut.c +++ b/test/unit/lib/nvmf/ctrlr.c/ctrlr_ut.c @@ -883,6 +883,9 @@ test_get_ns_id_desc_list(void) req.xfer = SPDK_NVME_DATA_CONTROLLER_TO_HOST; req.data = buf; req.length = sizeof(buf); + req.iovcnt = 1; + req.iov[0].iov_base = req.data; + req.iov[0].iov_len = req.length; memset(&cmd, 0, sizeof(cmd)); cmd.nvme_cmd.opc = SPDK_NVME_OPC_IDENTIFY;