nvmf: add bounds checks to RW and DSM commands

Check that the number of blocks/ranges in the command fits within the
length specified by the SGL.

Change-Id: I21aded797dc1f1e752fe0bc9cec27310a4fb106a
Signed-off-by: Daniel Verkamp <daniel.verkamp@intel.com>
This commit is contained in:
Daniel Verkamp 2016-08-26 13:05:29 -07:00
parent a1d83c72bc
commit 11c5620ae4

View File

@ -385,6 +385,7 @@ nvmf_virtual_ctrlr_rw_cmd(struct spdk_bdev *bdev, struct spdk_nvmf_request *req)
{
uint64_t lba_address;
uint64_t blockcnt;
uint64_t io_bytes;
off_t offset;
uint64_t llen;
struct spdk_nvme_cmd *cmd = &req->cmd->nvme_cmd;
@ -403,6 +404,13 @@ nvmf_virtual_ctrlr_rw_cmd(struct spdk_bdev *bdev, struct spdk_nvmf_request *req)
return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE;
}
io_bytes = llen * bdev->blocklen;
if (io_bytes > req->length) {
SPDK_ERRLOG("Read/Write NLB > SGL length\n");
response->status.sc = SPDK_NVME_SC_DATA_SGL_LENGTH_INVALID;
return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE;
}
if (cmd->opc == SPDK_NVME_OPC_READ) {
spdk_trace_record(TRACE_NVMF_LIB_READ_START, 0, 0, (uint64_t)req, 0);
if (spdk_bdev_read(bdev, req->data, req->length, offset, nvmf_virtual_ctrlr_complete_cmd,
@ -449,6 +457,12 @@ nvmf_virtual_ctrlr_dsm_cmd(struct spdk_bdev *bdev, struct spdk_nvmf_request *req
bool async = false;
nr = ((cmd->cdw10 & 0x000000ff) + 1);
if (nr * sizeof(struct spdk_nvme_dsm_range) > req->length) {
SPDK_ERRLOG("Dataset Management number of ranges > SGL length\n");
response->status.sc = SPDK_NVME_SC_DATA_SGL_LENGTH_INVALID;
return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE;
}
attribute = cmd->cdw11 & 0x00000007;
if (attribute & SPDK_NVME_DSM_ATTR_DEALLOCATE) {
struct spdk_nvme_dsm_range *dsm_range = (struct spdk_nvme_dsm_range *)req->data;