subsystem: check for NULL bufs in reservation ops.

At the RDMA level, we allow processing requests that should contain a
data transfer, but specify a length of zero to be passed up the stack
without a data buffer. See spdk_nvmf_rdma_request_get_xfer. In the case
of the reservation requests, we weren't checking whether req->data was
NULL before trying to copy into it causing us to segfault if we got a
malformed reservation request.

Found when using the fuzzer.

Change-Id: I320174ec72a8d298ab6ca44ef6a99691631f00ca
Signed-off-by: Seth Howell <seth.howell@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/451786
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
Seth Howell 2019-04-23 15:28:54 -07:00 committed by Jim Harris
parent 795134891e
commit 3856d82b50

View File

@ -1583,7 +1583,14 @@ nvmf_ns_reservation_register(struct spdk_nvmf_ns *ns,
rrega = cmd->cdw10 & 0x7u;
iekey = (cmd->cdw10 >> 3) & 0x1u;
cptpl = (cmd->cdw10 >> 30) & 0x3u;
memcpy(&key, req->data, sizeof(key));
if (req->data && req->length >= sizeof(key)) {
memcpy(&key, req->data, sizeof(key));
} else {
SPDK_ERRLOG("No key provided. Failing request.\n");
status = SPDK_NVME_SC_INVALID_FIELD;
goto exit;
}
SPDK_DEBUGLOG(SPDK_LOG_NVMF, "REGISTER: RREGA %u, IEKEY %u, CPTPL %u, "
"NRKEY 0x%"PRIx64", NRKEY 0x%"PRIx64"\n",
@ -1697,7 +1704,14 @@ nvmf_ns_reservation_acquire(struct spdk_nvmf_ns *ns,
racqa = cmd->cdw10 & 0x7u;
iekey = (cmd->cdw10 >> 3) & 0x1u;
rtype = (cmd->cdw10 >> 8) & 0xffu;
memcpy(&key, req->data, sizeof(key));
if (req->data && req->length >= sizeof(key)) {
memcpy(&key, req->data, sizeof(key));
} else {
SPDK_ERRLOG("No key provided. Failing request.\n");
status = SPDK_NVME_SC_INVALID_FIELD;
goto exit;
}
SPDK_DEBUGLOG(SPDK_LOG_NVMF, "ACQUIRE: RACQA %u, IEKEY %u, RTYPE %u, "
"NRKEY 0x%"PRIx64", PRKEY 0x%"PRIx64"\n",
@ -1847,7 +1861,14 @@ nvmf_ns_reservation_release(struct spdk_nvmf_ns *ns,
rrela = cmd->cdw10 & 0x7u;
iekey = (cmd->cdw10 >> 3) & 0x1u;
rtype = (cmd->cdw10 >> 8) & 0xffu;
memcpy(&crkey, req->data, sizeof(crkey));
if (req->data && req->length >= sizeof(crkey)) {
memcpy(&crkey, req->data, sizeof(crkey));
} else {
SPDK_ERRLOG("No key provided. Failing request.\n");
status = SPDK_NVME_SC_INVALID_FIELD;
goto exit;
}
SPDK_DEBUGLOG(SPDK_LOG_NVMF, "RELEASE: RRELA %u, IEKEY %u, RTYPE %u, "
"CRKEY 0x%"PRIx64"\n", rrela, iekey, rtype, crkey);
@ -1939,6 +1960,13 @@ nvmf_ns_reservation_report(struct spdk_nvmf_ns *ns,
uint32_t regctl = 0;
uint8_t status = SPDK_NVME_SC_SUCCESS;
if (req->data == NULL) {
SPDK_ERRLOG("No data transfer specified for request. "
" Unable to transfer back response.\n");
status = SPDK_NVME_SC_INVALID_FIELD;
goto exit;
}
/* NVMeoF uses Extended Data Structure */
if ((cmd->cdw11 & 0x00000001u) == 0) {
SPDK_ERRLOG("NVMeoF uses extended controller data structure, "