Commit 3856d82b authored by Seth Howell's avatar Seth Howell Committed by Jim Harris
Browse files

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: default avatarSeth Howell <seth.howell@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/451786


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
parent 79513489
Loading
Loading
Loading
Loading
+31 −3
Original line number Diff line number Diff line
@@ -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;

	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;

	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;

	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, "