From: Kelvin Cao <kelvin.cao@xxxxxxxxxxxxx> 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@xxxxxxxxxxxxx> [logang@xxxxxxxxxxxx: rework commit message] Signed-off-by: Logan Gunthorpe <logang@xxxxxxxxxxxx> --- drivers/pci/switch/switchtec.c | 6 ++++++ include/linux/switchtec.h | 5 +++++ 2 files changed, 11 insertions(+) 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 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, -- 2.20.1