nvmf: check HOSTNQN access right for discovery service

Initiator can use `nvme discover` command to display all
the subsystem's information, because we don't check
the allowed HOSTNQN for Discovery service, so here
adding this feature so that only return the log pages
to the allowed hosts.

Fix issue #576.

Change-Id: I51e6770bd67ea0b41caf9de3a8899923377e6255
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/462440
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: yidong0635 <dongx.yi@intel.com>
This commit is contained in:
Changpeng Liu 2019-07-18 04:40:33 -04:00
parent 234eb48bf6
commit 3fe300609e
6 changed files with 22 additions and 12 deletions

View File

@ -1491,7 +1491,8 @@ spdk_nvmf_ctrlr_get_log_page(struct spdk_nvmf_request *req)
if (subsystem->subtype == SPDK_NVMF_SUBTYPE_DISCOVERY) {
switch (lid) {
case SPDK_NVME_LOG_DISCOVERY:
spdk_nvmf_get_discovery_log_page(subsystem->tgt, req->iov, req->iovcnt, offset, len);
spdk_nvmf_get_discovery_log_page(subsystem->tgt, ctrlr->hostnqn, req->iov, req->iovcnt, offset,
len);
return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE;
default:
goto invalid_log_page;

View File

@ -49,7 +49,7 @@
#include "spdk_internal/log.h"
static void
nvmf_update_discovery_log(struct spdk_nvmf_tgt *tgt)
nvmf_update_discovery_log(struct spdk_nvmf_tgt *tgt, const char *hostnqn)
{
uint64_t numrec = 0;
struct spdk_nvmf_subsystem *subsystem;
@ -81,6 +81,10 @@ nvmf_update_discovery_log(struct spdk_nvmf_tgt *tgt)
continue;
}
if (!spdk_nvmf_subsystem_host_allowed(subsystem, hostnqn)) {
continue;
}
for (listener = spdk_nvmf_subsystem_get_first_listener(subsystem); listener != NULL;
listener = spdk_nvmf_subsystem_get_next_listener(subsystem, listener)) {
size_t new_size = cur_size + sizeof(*entry);
@ -118,7 +122,7 @@ nvmf_update_discovery_log(struct spdk_nvmf_tgt *tgt)
}
void
spdk_nvmf_get_discovery_log_page(struct spdk_nvmf_tgt *tgt, struct iovec *iov,
spdk_nvmf_get_discovery_log_page(struct spdk_nvmf_tgt *tgt, const char *hostnqn, struct iovec *iov,
uint32_t iovcnt, uint64_t offset, uint32_t length)
{
size_t copy_len = 0;
@ -127,7 +131,7 @@ spdk_nvmf_get_discovery_log_page(struct spdk_nvmf_tgt *tgt, struct iovec *iov,
if (tgt->discovery_log_page == NULL ||
tgt->discovery_log_page->genctr != tgt->discovery_genctr) {
nvmf_update_discovery_log(tgt);
nvmf_update_discovery_log(tgt, hostnqn);
}
/* Copy the valid part of the discovery log page, if any */

View File

@ -375,7 +375,8 @@ int spdk_nvmf_request_complete(struct spdk_nvmf_request *req);
bool spdk_nvmf_request_get_dif_ctx(struct spdk_nvmf_request *req, struct spdk_dif_ctx *dif_ctx);
void spdk_nvmf_get_discovery_log_page(struct spdk_nvmf_tgt *tgt, struct iovec *iov,
void spdk_nvmf_get_discovery_log_page(struct spdk_nvmf_tgt *tgt, const char *hostnqn,
struct iovec *iov,
uint32_t iovcnt, uint64_t offset, uint32_t length);
void spdk_nvmf_ctrlr_destruct(struct spdk_nvmf_ctrlr *ctrlr);

View File

@ -103,7 +103,8 @@ DEFINE_STUB(spdk_nvmf_ctrlr_write_zeroes_supported,
false);
DEFINE_STUB_V(spdk_nvmf_get_discovery_log_page,
(struct spdk_nvmf_tgt *tgt, struct iovec *iov, uint32_t iovcnt, uint64_t offset, uint32_t length));
(struct spdk_nvmf_tgt *tgt, const char *hostnqn, struct iovec *iov,
uint32_t iovcnt, uint64_t offset, uint32_t length));
DEFINE_STUB(spdk_nvmf_qpair_get_listen_trid,
int,

View File

@ -220,6 +220,7 @@ test_discovery_log(void)
/* Add one subsystem and verify that the discovery log contains it */
subsystem = spdk_nvmf_subsystem_create(&tgt, "nqn.2016-06.io.spdk:subsystem1",
SPDK_NVMF_SUBTYPE_NVME, 0);
subsystem->allow_any_host = true;
SPDK_CU_ASSERT_FATAL(subsystem != NULL);
trid.trtype = SPDK_NVME_TRANSPORT_RDMA;
@ -232,20 +233,21 @@ test_discovery_log(void)
/* Get only genctr (first field in the header) */
memset(buffer, 0xCC, sizeof(buffer));
disc_log = (struct spdk_nvmf_discovery_log_page *)buffer;
spdk_nvmf_get_discovery_log_page(&tgt, &iov, 1, 0, sizeof(disc_log->genctr));
spdk_nvmf_get_discovery_log_page(&tgt, "nqn.2016-06.io.spdk:host1", &iov, 1, 0,
sizeof(disc_log->genctr));
CU_ASSERT(disc_log->genctr == 1); /* one added subsystem */
/* Get only the header, no entries */
memset(buffer, 0xCC, sizeof(buffer));
disc_log = (struct spdk_nvmf_discovery_log_page *)buffer;
spdk_nvmf_get_discovery_log_page(&tgt, &iov, 1, 0, sizeof(*disc_log));
spdk_nvmf_get_discovery_log_page(&tgt, "nqn.2016-06.io.spdk:host1", &iov, 1, 0, sizeof(*disc_log));
CU_ASSERT(disc_log->genctr == 1);
CU_ASSERT(disc_log->numrec == 1);
/* Offset 0, exact size match */
memset(buffer, 0xCC, sizeof(buffer));
disc_log = (struct spdk_nvmf_discovery_log_page *)buffer;
spdk_nvmf_get_discovery_log_page(&tgt, &iov, 1, 0,
spdk_nvmf_get_discovery_log_page(&tgt, "nqn.2016-06.io.spdk:host1", &iov, 1, 0,
sizeof(*disc_log) + sizeof(disc_log->entries[0]));
CU_ASSERT(disc_log->genctr != 0);
CU_ASSERT(disc_log->numrec == 1);
@ -254,7 +256,7 @@ test_discovery_log(void)
/* Offset 0, oversize buffer */
memset(buffer, 0xCC, sizeof(buffer));
disc_log = (struct spdk_nvmf_discovery_log_page *)buffer;
spdk_nvmf_get_discovery_log_page(&tgt, &iov, 1, 0, sizeof(buffer));
spdk_nvmf_get_discovery_log_page(&tgt, "nqn.2016-06.io.spdk:host1", &iov, 1, 0, sizeof(buffer));
CU_ASSERT(disc_log->genctr != 0);
CU_ASSERT(disc_log->numrec == 1);
CU_ASSERT(disc_log->entries[0].trtype == 42);
@ -264,7 +266,7 @@ test_discovery_log(void)
/* Get just the first entry, no header */
memset(buffer, 0xCC, sizeof(buffer));
entry = (struct spdk_nvmf_discovery_log_page_entry *)buffer;
spdk_nvmf_get_discovery_log_page(&tgt, &iov,
spdk_nvmf_get_discovery_log_page(&tgt, "nqn.2016-06.io.spdk:host1", &iov,
1,
offsetof(struct spdk_nvmf_discovery_log_page, entries[0]),
sizeof(*entry));

View File

@ -90,7 +90,8 @@ DEFINE_STUB(spdk_nvmf_transport_qpair_set_sqsize,
0);
DEFINE_STUB_V(spdk_nvmf_get_discovery_log_page,
(struct spdk_nvmf_tgt *tgt, struct iovec *iov, uint32_t iovcnt, uint64_t offset, uint32_t length));
(struct spdk_nvmf_tgt *tgt, const char *hostnqn, struct iovec *iov,
uint32_t iovcnt, uint64_t offset, uint32_t length));
DEFINE_STUB_V(spdk_nvmf_subsystem_remove_ctrlr,
(struct spdk_nvmf_subsystem *subsystem, struct spdk_nvmf_ctrlr *ctrlr));