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:
parent
a1d83c72bc
commit
11c5620ae4
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user