linux-nvme.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [RFC 0/2] Split out firmware upgrade from CAP_SYS_ADMIN
@ 2021-02-18 17:09 Mario Limonciello
  2021-02-18 17:09 ` [RFC 1/2] capability: Introduce CAP_FIRMWARE_UPGRADE Mario Limonciello
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Mario Limonciello @ 2021-02-18 17:09 UTC (permalink / raw)
  To: Keith Busch
  Cc: Sagi Grimberg, Mario Limonciello, campello, Richard Hughes, LKML,
	linux-nvme, Jens Axboe, jorgelo, Christoph Hellwig

Currently NVME (and probably other drivers) require CAP_SYS_ADMIN to
send all commands to the device.  This means that software running
in userspace needs the stronger CAP_SYS_ADMIN permission when realistically
a more limited subset of functionality is actually needed.

To allow software that performs firmware upgrades to run without CAP_SYS_ADMIN,
create a new capability CAP_FIRMWARE_UPGRADE that software can run with.

For the RFC, only include NVME.  Other drivers can be added if suggested.

Mario Limonciello (2):
  capability: Introduce CAP_FIRMWARE_UPGRADE
  nvme: Use CAP_FIRMWARE_UPGRADE to check user commands

 drivers/nvme/host/core.c            | 28 ++++++++++++++++++++++++----
 include/linux/capability.h          |  5 +++++
 include/uapi/linux/capability.h     |  7 ++++++-
 security/selinux/include/classmap.h |  4 ++--
 4 files changed, 37 insertions(+), 7 deletions(-)

-- 
2.25.1


_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [RFC 1/2] capability: Introduce CAP_FIRMWARE_UPGRADE
  2021-02-18 17:09 [RFC 0/2] Split out firmware upgrade from CAP_SYS_ADMIN Mario Limonciello
@ 2021-02-18 17:09 ` Mario Limonciello
  2021-02-18 17:09 ` [RFC 2/2] nvme: Use CAP_FIRMWARE_UPGRADE to check user commands Mario Limonciello
  2021-07-23  0:59 ` [RFC 0/2] Split out firmware upgrade from CAP_SYS_ADMIN Daniil Lunev
  2 siblings, 0 replies; 4+ messages in thread
From: Mario Limonciello @ 2021-02-18 17:09 UTC (permalink / raw)
  To: Keith Busch
  Cc: Sagi Grimberg, Mario Limonciello, campello, Richard Hughes, LKML,
	linux-nvme, Jens Axboe, jorgelo, Christoph Hellwig

Split out permissions specifically for firmware upgrades from
CAP_SYS_ADMIN to a new separate capability.  This will allow userspace
applications that would traditionally have needed CAP_SYS_ADMIN to perform
firmware upgrades to have a reduced permission set.

Signed-off-by: Mario Limonciello <mario.limonciello@dell.com>
---
 include/linux/capability.h          | 5 +++++
 include/uapi/linux/capability.h     | 7 ++++++-
 security/selinux/include/classmap.h | 4 ++--
 3 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/include/linux/capability.h b/include/linux/capability.h
index b2f698915c0f..e9233e217402 100644
--- a/include/linux/capability.h
+++ b/include/linux/capability.h
@@ -267,6 +267,11 @@ static inline bool checkpoint_restore_ns_capable(struct user_namespace *ns)
 		ns_capable(ns, CAP_SYS_ADMIN);
 }
 
+static inline bool firmware_upgrade_capable(void)
+{
+	return capable(CAP_FIRMWARE_UPGRADE) || capable(CAP_SYS_ADMIN);
+}
+
 /* audit system wants to get cap info from files as well */
 extern int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data *cpu_caps);
 
diff --git a/include/uapi/linux/capability.h b/include/uapi/linux/capability.h
index c6ca33034147..0f204c6a1c0b 100644
--- a/include/uapi/linux/capability.h
+++ b/include/uapi/linux/capability.h
@@ -275,6 +275,7 @@ struct vfs_ns_cap_data {
 /* Allow setting encryption key on loopback filesystem */
 /* Allow setting zone reclaim policy */
 /* Allow everything under CAP_BPF and CAP_PERFMON for backward compatibility */
+/* Allow everything under CAP_FIRMWARE_UPGRADE for backward compatibility */
 
 #define CAP_SYS_ADMIN        21
 
@@ -417,7 +418,11 @@ struct vfs_ns_cap_data {
 
 #define CAP_CHECKPOINT_RESTORE	40
 
-#define CAP_LAST_CAP         CAP_CHECKPOINT_RESTORE
+/* Allow a device firmware upgrade */
+
+#define CAP_FIRMWARE_UPGRADE	41
+
+#define CAP_LAST_CAP         CAP_FIRMWARE_UPGRADE
 
 #define cap_valid(x) ((x) >= 0 && (x) <= CAP_LAST_CAP)
 
diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h
index 40cebde62856..188318eefb41 100644
--- a/security/selinux/include/classmap.h
+++ b/security/selinux/include/classmap.h
@@ -28,9 +28,9 @@
 
 #define COMMON_CAP2_PERMS  "mac_override", "mac_admin", "syslog", \
 		"wake_alarm", "block_suspend", "audit_read", "perfmon", "bpf", \
-		"checkpoint_restore"
+		"checkpoint_restore", "firmware_upgrade"
 
-#if CAP_LAST_CAP > CAP_CHECKPOINT_RESTORE
+#if CAP_LAST_CAP > CAP_FIRMWARE_UPGRADE
 #error New capability defined, please update COMMON_CAP2_PERMS.
 #endif
 
-- 
2.25.1


_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [RFC 2/2] nvme: Use CAP_FIRMWARE_UPGRADE to check user commands
  2021-02-18 17:09 [RFC 0/2] Split out firmware upgrade from CAP_SYS_ADMIN Mario Limonciello
  2021-02-18 17:09 ` [RFC 1/2] capability: Introduce CAP_FIRMWARE_UPGRADE Mario Limonciello
@ 2021-02-18 17:09 ` Mario Limonciello
  2021-07-23  0:59 ` [RFC 0/2] Split out firmware upgrade from CAP_SYS_ADMIN Daniil Lunev
  2 siblings, 0 replies; 4+ messages in thread
From: Mario Limonciello @ 2021-02-18 17:09 UTC (permalink / raw)
  To: Keith Busch
  Cc: Sagi Grimberg, Mario Limonciello, campello, Richard Hughes, LKML,
	linux-nvme, Jens Axboe, jorgelo, Christoph Hellwig

Software that is running with CAP_FIRMWARE_UPGRADE needs a limited
set of opcode access:
* Identify the disk
* Download firmware to the disk
* Commit the firmwware to the disk

Signed-off-by: Mario Limonciello <mario.limonciello@dell.com>
---
 drivers/nvme/host/core.c | 28 ++++++++++++++++++++++++----
 1 file changed, 24 insertions(+), 4 deletions(-)

diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index f13eb4ded95f..80be3d6b7437 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -1593,13 +1593,23 @@ static int nvme_user_cmd(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
 	u64 result;
 	int status;
 
-	if (!capable(CAP_SYS_ADMIN))
-		return -EACCES;
 	if (copy_from_user(&cmd, ucmd, sizeof(cmd)))
 		return -EFAULT;
 	if (cmd.flags)
 		return -EINVAL;
 
+	switch (cmd.opcode) {
+	case nvme_admin_identify:
+	case nvme_admin_activate_fw:
+	case nvme_admin_download_fw:
+		if (!firmware_upgrade_capable())
+			return -EACCES;
+		break;
+	default:
+		if (!capable(CAP_SYS_ADMIN))
+			return -EACCES;
+	}
+
 	memset(&c, 0, sizeof(c));
 	c.common.opcode = cmd.opcode;
 	c.common.flags = cmd.flags;
@@ -1637,13 +1647,23 @@ static int nvme_user_cmd64(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
 	unsigned timeout = 0;
 	int status;
 
-	if (!capable(CAP_SYS_ADMIN))
-		return -EACCES;
 	if (copy_from_user(&cmd, ucmd, sizeof(cmd)))
 		return -EFAULT;
 	if (cmd.flags)
 		return -EINVAL;
 
+	switch (cmd.opcode) {
+	case nvme_admin_identify:
+	case nvme_admin_activate_fw:
+	case nvme_admin_download_fw:
+		if (!firmware_upgrade_capable())
+			return -EACCES;
+		break;
+	default:
+		if (!capable(CAP_SYS_ADMIN))
+			return -EACCES;
+	}
+
 	memset(&c, 0, sizeof(c));
 	c.common.opcode = cmd.opcode;
 	c.common.flags = cmd.flags;
-- 
2.25.1


_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [RFC 0/2] Split out firmware upgrade from CAP_SYS_ADMIN
  2021-02-18 17:09 [RFC 0/2] Split out firmware upgrade from CAP_SYS_ADMIN Mario Limonciello
  2021-02-18 17:09 ` [RFC 1/2] capability: Introduce CAP_FIRMWARE_UPGRADE Mario Limonciello
  2021-02-18 17:09 ` [RFC 2/2] nvme: Use CAP_FIRMWARE_UPGRADE to check user commands Mario Limonciello
@ 2021-07-23  0:59 ` Daniil Lunev
  2 siblings, 0 replies; 4+ messages in thread
From: Daniil Lunev @ 2021-07-23  0:59 UTC (permalink / raw)
  To: kbusch
  Cc: Mario.limonciello, axboe, campello, hch, hughsient, jorgelo,
	linux-kernel, linux-nvme, sagi

Signal boost on this thread for we are interested in a mechanism like that to
avoid running firmware updater with root privileges. We are looking into using
the mechanism to be able to update NVMe and SATA devices from a user with
limited permissions, and to tighten the security for eMMC device, which
currently require only RAW_IO capability to perform a firmware upgrade.

_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2021-07-23  1:00 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-18 17:09 [RFC 0/2] Split out firmware upgrade from CAP_SYS_ADMIN Mario Limonciello
2021-02-18 17:09 ` [RFC 1/2] capability: Introduce CAP_FIRMWARE_UPGRADE Mario Limonciello
2021-02-18 17:09 ` [RFC 2/2] nvme: Use CAP_FIRMWARE_UPGRADE to check user commands Mario Limonciello
2021-07-23  0:59 ` [RFC 0/2] Split out firmware upgrade from CAP_SYS_ADMIN Daniil Lunev

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).