* [PATCH] nvmet: verify the hostid when looking up a controller
@ 2026-08-18 16:29 Chuyf26
0 siblings, 0 replies; 2+ messages in thread
From: Chuyf26 @ 2026-08-18 16:29 UTC (permalink / raw)
To: linux-nvme
nvmet_ctrl_find_get() matches controllers by cntlid and hostnqn only.
The hostnqn is not a secret: any host that can reach the subsystem can
put an arbitrary NQN into its connect data. A malicious host knowing
or guessing the NQN and controller ID of another host (controller IDs
are allocated sequentially) can therefore attach its queues to that
host's controller, issue commands on its behalf, or disturb its I/O by
tearing down the shared controller state.
The path is: an unauthenticated host sends a fabrics CONNECT command,
nvmet_execute_fabrics_connect() parses the connect data capsule and
hands subsysnqn, hostnqn and cntlid to nvmet_ctrl_find_get(), which
returns the first matching controller. The connect data also carries
the host's hostid, but it is never compared.
Also require the hostid from the connect data to match the controller's
hostid. The hostid identifies the host installation and is generated
locally, so it cannot be chosen by an attacker to impersonate another
host. Controllers that were created without a hostid keep the old
behaviour.
Fixes: a07b4970f464 ("nvmet: add a generic NVMe target")
Reported-by: Abaci <abaci@linux.alibaba.com>
Assisted-by: abaci:qwen3.8-max
Signed-off-by: Chuyf26 <Chuyf26@linux.alibaba.com>
---
drivers/nvme/target/core.c | 12 ++++++++++++
drivers/nvme/target/fabrics-cmd.c | 2 +-
drivers/nvme/target/nvmet.h | 1 +
3 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c
index 7b6309d866be..64a5fa951bca 100644
--- a/drivers/nvme/target/core.c
+++ b/drivers/nvme/target/core.c
@@ -1287,6 +1287,7 @@ static void nvmet_init_cap(struct nvmet_ctrl *ctrl)
struct nvmet_ctrl *nvmet_ctrl_find_get(const char *subsysnqn,
const char *hostnqn, u16 cntlid,
+ const uuid_t *hostid,
struct nvmet_req *req)
{
struct nvmet_ctrl *ctrl = NULL;
@@ -1307,6 +1308,17 @@ struct nvmet_ctrl *nvmet_ctrl_find_get(const char *subsysnqn,
pr_warn("hostnqn mismatch.\n");
continue;
}
+ /* hostnqn alone does not identify a host: any host
+ * able to connect to the subsystem can claim it.
+ * Also require the hostid, which identifies the host
+ * installation, to match. Accept a nil hostid only
+ * if the controller was created without one.
+ */
+ if (!uuid_is_null(&ctrl->hostid) &&
+ !uuid_equal(&ctrl->hostid, hostid)) {
+ pr_warn("hostid mismatch.\n");
+ continue;
+ }
if (!kref_get_unless_zero(&ctrl->ref))
continue;
diff --git a/drivers/nvme/target/fabrics-cmd.c b/drivers/nvme/target/fabrics-cmd.c
index e008f162ce68..9e0573b2aec9 100644
--- a/drivers/nvme/target/fabrics-cmd.c
+++ b/drivers/nvme/target/fabrics-cmd.c
@@ -311,7 +311,7 @@ static void nvmet_execute_io_connect(struct nvmet_req *req)
d->subsysnqn[NVMF_NQN_FIELD_LEN - 1] = '\0';
d->hostnqn[NVMF_NQN_FIELD_LEN - 1] = '\0';
ctrl = nvmet_ctrl_find_get(d->subsysnqn, d->hostnqn,
- le16_to_cpu(d->cntlid), req);
+ le16_to_cpu(d->cntlid), &d->hostid, req);
if (!ctrl) {
status = NVME_SC_CONNECT_INVALID_PARAM | NVME_SC_DNR;
goto out;
diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h
index 9aef41c26415..137860ec4b28 100644
--- a/drivers/nvme/target/nvmet.h
+++ b/drivers/nvme/target/nvmet.h
@@ -532,6 +532,7 @@ u16 nvmet_alloc_ctrl(const char *subsysnqn, const char *hostnqn,
uuid_t *hostid);
struct nvmet_ctrl *nvmet_ctrl_find_get(const char *subsysnqn,
const char *hostnqn, u16 cntlid,
+ const uuid_t *hostid,
struct nvmet_req *req);
void nvmet_ctrl_put(struct nvmet_ctrl *ctrl);
u16 nvmet_check_ctrl_status(struct nvmet_req *req);
--
2.43.5
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] nvmet: verify the hostid when looking up a controller
[not found] <20260818162551.1AFD768CFE@verein.lst.de>
@ 2026-08-19 5:51 ` Christoph Hellwig
0 siblings, 0 replies; 2+ messages in thread
From: Christoph Hellwig @ 2026-08-19 5:51 UTC (permalink / raw)
To: Chuyf26; +Cc: Keith Busch, Sagi Grimberg, Christoph Hellwig, linux-nvme
On Tue, Aug 18, 2026 at 06:25:51PM +0200, Chuyf26 wrote:
> nvmet_ctrl_find_get() matches controllers by cntlid and hostnqn only.
> The hostnqn is not a secret: any host that can reach the subsystem can
> put an arbitrary NQN into its connect data. A malicious host knowing
> or guessing the NQN and controller ID of another host (controller IDs
> are allocated sequentially) can therefore attach its queues to that
> host's controller, issue commands on its behalf, or disturb its I/O by
> tearing down the shared controller state.
Yes.
> Also require the hostid from the connect data to match the controller's
> hostid. The hostid identifies the host installation and is generated
> locally, so it cannot be chosen by an attacker to impersonate another
> host. Controllers that were created without a hostid keep the old
> behaviour.
Of course it can. Please don't send completely useless LLM garbage,
thank you!
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-08-19 5:51 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20260818162551.1AFD768CFE@verein.lst.de>
2026-08-19 5:51 ` [PATCH] nvmet: verify the hostid when looking up a controller Christoph Hellwig
2026-08-18 16:29 Chuyf26
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.