[prev in list] [next in list] [prev in thread] [next in thread] 

List:       git-commits-head
Subject:    nvme: consult the CSE log page for unprivileged passthrough
From:       Linux Kernel Mailing List <linux-kernel () vger ! kernel ! org>
Date:       2022-12-30 0:53:54
Message-ID: git-mailbomb-linux-master-6f99ac04c469b5d0a180a4ccea99d25d5dc9d21c () kernel ! org
[Download RAW message or body]

Commit:     6f99ac04c469b5d0a180a4ccea99d25d5dc9d21c
Parent:     831ed60c2aca2d7c517b2da22897a90224a97d27
Refname:    refs/heads/master
Web:        https://git.kernel.org/torvalds/c/6f99ac04c469b5d0a180a4ccea99d25d5dc9d21c
Author:     Christoph Hellwig <hch@lst.de>
AuthorDate: Tue Dec 13 16:13:38 2022 +0100
Committer:  Christoph Hellwig <hch@lst.de>
CommitDate: Wed Dec 28 06:26:31 2022 -1000

    nvme: consult the CSE log page for unprivileged passthrough
    
    Commands like Write Zeros can change the contents of a namespaces without
    actually transferring data.  To protect against this, check the Commands
    Supported and Effects log is supported by the controller for any
    unprivileg command passthrough and refuse unprivileged passthrough if the
    command has any effects that can change data or metadata.
    
    Note: While the Commands Support and Effects log page has only been
    mandatory since NVMe 2.0, it is widely supported because Windows requires
    it for any command passthrough from userspace.
    
    Fixes: e4fbcf32c860 ("nvme: identify-namespace without CAP_SYS_ADMIN")
    Signed-off-by: Christoph Hellwig <hch@lst.de>
    Reviewed-by: Keith Busch <kbusch@kernel.org>
    Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
    Reviewed-by: Kanchan Joshi <joshi.k@samsung.com>
---
 drivers/nvme/host/ioctl.c | 28 ++++++++++++++++++++++++----
 include/linux/nvme.h      |  1 +
 2 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/drivers/nvme/host/ioctl.c b/drivers/nvme/host/ioctl.c
index 9ddda571f0461..a8639919237e6 100644
--- a/drivers/nvme/host/ioctl.c
+++ b/drivers/nvme/host/ioctl.c
@@ -11,6 +11,8 @@
 static bool nvme_cmd_allowed(struct nvme_ns *ns, struct nvme_command *c,
 		fmode_t mode)
 {
+	u32 effects;
+
 	if (capable(CAP_SYS_ADMIN))
 		return true;
 
@@ -43,11 +45,29 @@ static bool nvme_cmd_allowed(struct nvme_ns *ns, struct nvme_command *c,
 	}
 
 	/*
-	 * Only allow I/O commands that transfer data to the controller if the
-	 * special file is open for writing, but always allow I/O commands that
-	 * transfer data from the controller.
+	 * Check if the controller provides a Commands Supported and Effects log
+	 * and marks this command as supported.  If not reject unprivileged
+	 * passthrough.
+	 */
+	effects = nvme_command_effects(ns->ctrl, ns, c->common.opcode);
+	if (!(effects & NVME_CMD_EFFECTS_CSUPP))
+		return false;
+
+	/*
+	 * Don't allow passthrough for command that have intrusive (or unknown)
+	 * effects.
+	 */
+	if (effects & ~(NVME_CMD_EFFECTS_CSUPP | NVME_CMD_EFFECTS_LBCC |
+			NVME_CMD_EFFECTS_UUID_SEL |
+			NVME_CMD_EFFECTS_SCOPE_MASK))
+		return false;
+
+	/*
+	 * Only allow I/O commands that transfer data to the controller or that
+	 * change the logical block contents if the file descriptor is open for
+	 * writing.
 	 */
-	if (nvme_is_write(c))
+	if (nvme_is_write(c) || (effects & NVME_CMD_EFFECTS_LBCC))
 		return mode & FMODE_WRITE;
 	return true;
 }
diff --git a/include/linux/nvme.h b/include/linux/nvme.h
index d1cd53f2b6abd..4fad4aa245fb0 100644
--- a/include/linux/nvme.h
+++ b/include/linux/nvme.h
@@ -642,6 +642,7 @@ enum {
 	NVME_CMD_EFFECTS_CCC		= 1 << 4,
 	NVME_CMD_EFFECTS_CSE_MASK	= GENMASK(18, 16),
 	NVME_CMD_EFFECTS_UUID_SEL	= 1 << 19,
+	NVME_CMD_EFFECTS_SCOPE_MASK	= GENMASK(31, 20),
 };
 
 struct nvme_effects_log {
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic