PCI/switchtec: Add Gen4 MRPC GAS access permission check
authorKelvin Cao <kelvin.cao@microchip.com>
Mon, 6 Jan 2020 19:03:35 +0000 (12:03 -0700)
committerBjorn Helgaas <bhelgaas@google.com>
Wed, 15 Jan 2020 17:00:39 +0000 (11:00 -0600)
Gen4 hardware provides new MRPC commands to read and write directly from
any address in the PCI BAR (which Microsemi refers to as GAS). Since
accessing BARs can be dangerous and break the driver, we don't want
unprivileged users to have this ability.

Therefore, require CAP_SYS_ADMIN for the local and remote GAS access MRPC
commands. Privileged 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.

[logang@deltatee.com: rework commit message]
Link: https://lore.kernel.org/r/20200106190337.2428-11-logang@deltatee.com
Signed-off-by: Kelvin Cao <kelvin.cao@microchip.com>
Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
drivers/pci/switch/switchtec.c
include/linux/switchtec.h

index af85d23..92b95e8 100644 (file)
@@ -479,6 +479,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));
index e851552..082f1d5 100644 (file)
 #define SWITCHTEC_EVENT_FATAL    BIT(4)
 
 #define SWITCHTEC_DMA_MRPC_EN  BIT(0)
+
+#define MRPC_GAS_READ          0x29
+#define MRPC_GAS_WRITE         0x87
+#define MRPC_CMD_ID(x)         ((x) & 0xffff)
+
 enum {
        SWITCHTEC_GAS_MRPC_OFFSET       = 0x0000,
        SWITCHTEC_GAS_TOP_CFG_OFFSET    = 0x1000,