[RFC 2/2] nvme : Add ioctls for passthru admin whitelisting

Joel Granados j.granados at samsung.com
Fri Oct 7 06:22:56 PDT 2022


An ioctl (NVME_IOCTL_PTHRU_WLIST) is added in order to control the passthu
admin opcode whiltelist. A new struct (nvme_pthru_wlist) is used to pass
an action (Add, Remove, Test), opcode number and result data between user
and kernel space.

Signed-off-by: Joel Granados <j.granados at samsung.com>
---
 drivers/nvme/host/ioctl.c       | 32 ++++++++++++++++++++++++++++++++
 include/uapi/linux/nvme_ioctl.h | 14 ++++++++++++++
 2 files changed, 46 insertions(+)

diff --git a/drivers/nvme/host/ioctl.c b/drivers/nvme/host/ioctl.c
index 73e4287d2c44..76393d50a798 100644
--- a/drivers/nvme/host/ioctl.c
+++ b/drivers/nvme/host/ioctl.c
@@ -50,6 +50,36 @@ bool nvme_cmd_allowed(struct nvme_ns *ns, struct nvme_command *c, fmode_t mode)
 	return true;
 }
 
+static int nvme_admin_cmd_whitelist(struct nvme_pthru_wlist __user *u_op)
+{
+	__u8 opcode;
+	struct nvme_pthru_wlist nvme_pthru_wlist = {0};
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EACCES;
+	if (copy_from_user(&nvme_pthru_wlist, u_op, sizeof(struct nvme_pthru_wlist)))
+		return -EFAULT;
+	opcode = nvme_pthru_wlist.opcode;
+	if (opcode >= nvme_admin_last || opcode < 0)
+		return -EINVAL;
+
+	switch (nvme_pthru_wlist.action) {
+	case NVME_PTHRU_WLIST_ADD:
+		__set_bit(opcode, nvme_admin_whitelist);
+		return 0;
+	case NVME_PTHRU_WLIST_REM:
+		__clear_bit(opcode, nvme_admin_whitelist);
+		return 0;
+	case NVME_PTHRU_WLIST_TEST:
+		if (put_user(test_bit(opcode, nvme_admin_whitelist),
+			     &u_op->result))
+			return -EFAULT;
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
 static void *nvme_add_user_metadata(struct bio *bio, void __user *ubuf,
 		unsigned len, u32 seed, bool write)
 {
@@ -586,6 +616,8 @@ static int nvme_ns_ioctl(struct nvme_ns *ns, unsigned int cmd,
 		return nvme_user_cmd64(ns->ctrl, ns, argp, false, mode);
 	case NVME_IOCTL_IO64_CMD_VEC:
 		return nvme_user_cmd64(ns->ctrl, ns, argp, true, mode);
+	case NVME_IOCTL_PTHRU_WLIST:
+		return nvme_admin_cmd_whitelist(argp);
 	default:
 		return -ENOTTY;
 	}
diff --git a/include/uapi/linux/nvme_ioctl.h b/include/uapi/linux/nvme_ioctl.h
index 2f76cba67166..748ce70517ba 100644
--- a/include/uapi/linux/nvme_ioctl.h
+++ b/include/uapi/linux/nvme_ioctl.h
@@ -45,6 +45,19 @@ struct nvme_passthru_cmd {
 	__u32	result;
 };
 
+enum nvme_pthru_wlist_action {
+	NVME_PTHRU_WLIST_ADD,
+	NVME_PTHRU_WLIST_REM,
+	NVME_PTHRU_WLIST_TEST
+};
+
+struct nvme_pthru_wlist {
+	__u8				opcode;
+	__u8				flags;
+	__u32				result;
+	enum nvme_pthru_wlist_action	action;
+};
+
 struct nvme_passthru_cmd64 {
 	__u8	opcode;
 	__u8	flags;
@@ -104,6 +117,7 @@ struct nvme_uring_cmd {
 #define NVME_IOCTL_ADMIN64_CMD	_IOWR('N', 0x47, struct nvme_passthru_cmd64)
 #define NVME_IOCTL_IO64_CMD	_IOWR('N', 0x48, struct nvme_passthru_cmd64)
 #define NVME_IOCTL_IO64_CMD_VEC	_IOWR('N', 0x49, struct nvme_passthru_cmd64)
+#define NVME_IOCTL_PTHRU_WLIST	_IOWR('N', 0x50, struct nvme_pthru_wlist)
 
 /* io_uring async commands: */
 #define NVME_URING_CMD_IO	_IOWR('N', 0x80, struct nvme_uring_cmd)
-- 
2.30.2




More information about the Linux-nvme mailing list