Commit 8115a6e4 authored by Dor Deri's avatar Dor Deri Committed by Tomasz Zawadzki
Browse files

nvmf: validate NSID for controller/nvm scoped log page in get log page command



Adds NSID validation for log pages scoped to the controller or
NVM subsystem, in accordance with NVMe r1.4 specification:
"For log pages with a scope of NVM subsystem or controller (as shown
in Figure 195 and Figure 196), the controller should abort commands
that specify namespace identifiers other than 0h or FFFFFFFFh with
status Invalid Field in Command."

Change-Id: I74e69e3d7f0c32fc609417553ba40d5d23ece1a2
Signed-off-by: default avatarDor Deri <dor.deri@dell.com>
Reviewed-on: https://review.spdk.io/c/spdk/spdk/+/26581


Reviewed-by: default avatarJim Harris <jim.harris@nvidia.com>
Tested-by: default avatarSPDK Automated Test System <spdkbot@gmail.com>
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarChangpeng Liu <changpeliu@tencent.com>
parent 4201dfaf
Loading
Loading
Loading
Loading
+33 −1
Original line number Diff line number Diff line
@@ -2770,6 +2770,30 @@ nvmf_get_reservation_notification_log_page(struct spdk_nvmf_ctrlr *ctrlr,
	return 0;
}

static bool
is_log_page_ctrlr_nvm_scope(uint8_t lid)
{
	switch (lid) {
	case SPDK_NVME_LOG_SUPPORTED_LOG_PAGES:
	case SPDK_NVME_LOG_ERROR:
	case SPDK_NVME_LOG_FIRMWARE_SLOT:
	case SPDK_NVME_LOG_CHANGED_NS_LIST:
	case SPDK_NVME_LOG_COMMAND_EFFECTS_LOG:
	case SPDK_NVME_LOG_DEVICE_SELF_TEST:
	case SPDK_NVME_LOG_TELEMETRY_HOST_INITIATED:
	case SPDK_NVME_LOG_TELEMETRY_CTRLR_INITIATED:
	case SPDK_NVME_LOG_ENDURANCE_GROUP_INFORMATION:
	case SPDK_NVME_LOG_PREDICATBLE_LATENCY:
	case SPDK_NVME_LOG_PREDICTABLE_LATENCY_EVENT:
	case SPDK_NVME_LOG_ASYMMETRIC_NAMESPACE_ACCESS:
	case SPDK_NVME_LOG_PERSISTENT_EVENT_LOG:
	case SPDK_NVME_LOG_ENDURANCE_GROUP_EVENT:
		return true;
	default:
		return false;
	}
}

static int
nvmf_ctrlr_get_log_page(struct spdk_nvmf_request *req)
{
@@ -2780,7 +2804,7 @@ nvmf_ctrlr_get_log_page(struct spdk_nvmf_request *req)
	struct spdk_nvme_transport_id cmd_source_trid;
	uint64_t offset, len;
	uint32_t rae, numdl, numdu;
	uint8_t lid;
	uint8_t lid = cmd->cdw10_bits.get_log_page.lid;
	int rc = 0;

	if (req->iovcnt < 1) {
@@ -2788,6 +2812,14 @@ nvmf_ctrlr_get_log_page(struct spdk_nvmf_request *req)
		goto invalid_field_log_page;
	}

	if (is_log_page_ctrlr_nvm_scope(lid) &&
	    ((cmd->nsid != 0) && (cmd->nsid != SPDK_NVME_GLOBAL_NS_TAG))) {
		SPDK_ERRLOG("Invalid NSID: %u for log pages with a scope of NVM subsystem or controller: LID=0x%02X\n",
			    cmd->nsid, lid);
		goto invalid_field_log_page;
	}


	offset = (uint64_t)cmd->cdw12 | ((uint64_t)cmd->cdw13 << 32);
	if (offset & 3) {
		SPDK_ERRLOG("Invalid log page offset 0x%" PRIx64 ", Offset must be 4-byte aligned\n", offset);
+11 −0
Original line number Diff line number Diff line
@@ -428,6 +428,17 @@ test_get_log_page(void)
	CU_ASSERT(nvmf_ctrlr_get_log_page(&req) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE);
	CU_ASSERT(req.rsp->nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC);
	CU_ASSERT(req.rsp->nvme_cpl.status.sc == SPDK_NVME_SC_INVALID_FIELD);

	/* Get Log Page with controller scope using an NSID other than 0 or 0xFFFFFFFF */
	memset(&cmd, 0, sizeof(cmd));
	memset(&rsp, 0, sizeof(rsp));
	cmd.nvme_cmd.nsid = 1;
	cmd.nvme_cmd.opc = SPDK_NVME_OPC_GET_LOG_PAGE;
	cmd.nvme_cmd.cdw10_bits.get_log_page.lid = SPDK_NVME_LOG_ERROR;
	cmd.nvme_cmd.cdw10_bits.get_log_page.numdl = spdk_nvme_bytes_to_numd(req.length);
	CU_ASSERT(nvmf_ctrlr_get_log_page(&req) == SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE);
	CU_ASSERT(req.rsp->nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC);
	CU_ASSERT(req.rsp->nvme_cpl.status.sc == SPDK_NVME_SC_INVALID_FIELD);
}

static void