diff mbox series

[10/12] PCI/switchtec: Add permission check for the GAS access MRPC commands

Message ID 20200106190337.2428-11-logang@deltatee.com
State New
Headers show
Series Switchtec Fixes and Gen4 Support | expand

Commit Message

Logan Gunthorpe Jan. 6, 2020, 7:03 p.m. UTC
From: Kelvin Cao <kelvin.cao@microchip.com>

GEN4 hardware provides new MRPC commands to read and write from
directly from any address in the PCI BAR (which Microsemi refers to
as GAS). Seeing accessing BAR registers can be dangerous and break
the driver, we don't want unpriviliged users to have this ability.

Therefore, for the local and remote GAS access MRPC commands, the
requesting process should need CAP_SYS_ADMIN. Priviligded processes
will already have access to the bar through the sysfs resource file
so this doesn't give userspace any capabilities it didn't already have.

Signed-off-by: Kelvin Cao <kelvin.cao@microchip.com>
[logang@deltatee.com: rework commit message]
Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
 drivers/pci/switch/switchtec.c | 6 ++++++
 include/linux/switchtec.h      | 5 +++++
 2 files changed, 11 insertions(+)
diff mbox series


diff --git a/drivers/pci/switch/switchtec.c b/drivers/pci/switch/switchtec.c
index 524cb4e4bbf7..990e0ee32f7b 100644
--- a/drivers/pci/switch/switchtec.c
+++ b/drivers/pci/switch/switchtec.c
@@ -478,6 +478,12 @@  static ssize_t switchtec_dev_write(struct file *filp, const char __user *data,
 		rc = -EFAULT;
 		goto out;
+	if (((MRPC_CMD_ID(stuser->cmd) == MRPC_GAS_WRITE) ||
+	     (MRPC_CMD_ID(stuser->cmd) == MRPC_GAS_READ)) &&
+	    !capable(CAP_SYS_ADMIN)) {
+		rc = -EPERM;
+		goto out;
+	}
 	data += sizeof(stuser->cmd);
 	rc = copy_from_user(&stuser->data, data, size - sizeof(stuser->cmd));
diff --git a/include/linux/switchtec.h b/include/linux/switchtec.h
index e85155244135..1c3e76b535a2 100644
--- a/include/linux/switchtec.h
+++ b/include/linux/switchtec.h
@@ -21,6 +21,11 @@ 
+#define MRPC_GAS_READ 0x29
+#define MRPC_GAS_WRITE 0x87
+#define MRPC_CMD_ID(x) ((x) & 0xffff)
 enum {