18c8249
From 655fbf360e1481db4f06001f893d388c15ac307f Mon Sep 17 00:00:00 2001
6a91557
From: Matthew Garrett <matthew.garrett@nebula.com>
6a91557
Date: Thu, 8 Mar 2012 10:10:38 -0500
18c8249
Subject: [PATCH 02/20] PCI: Lock down BAR access when module security is
18c8249
 enabled
6a91557
6a91557
Any hardware that can potentially generate DMA has to be locked down from
6a91557
userspace in order to avoid it being possible for an attacker to modify
6a91557
kernel code, allowing them to circumvent disabled module loading or module
6a91557
signing. Default to paranoid - in future we can potentially relax this for
6a91557
sufficiently IOMMU-isolated devices.
6a91557
6a91557
Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
6a91557
---
6a91557
 drivers/pci/pci-sysfs.c | 10 ++++++++++
6a91557
 drivers/pci/proc.c      |  8 +++++++-
6a91557
 drivers/pci/syscall.c   |  3 ++-
6a91557
 3 files changed, 19 insertions(+), 2 deletions(-)
6a91557
6a91557
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
283bd06
index 312f23a8429c..93e6ac103dd0 100644
6a91557
--- a/drivers/pci/pci-sysfs.c
6a91557
+++ b/drivers/pci/pci-sysfs.c
6a91557
@@ -30,6 +30,7 @@
6a91557
 #include <linux/vgaarb.h>
6a91557
 #include <linux/pm_runtime.h>
6a91557
 #include <linux/of.h>
6a91557
+#include <linux/module.h>
6a91557
 #include "pci.h"
6a91557
 
6a91557
 static int sysfs_initialized;	/* = 0 */
283bd06
@@ -710,6 +711,9 @@ static ssize_t pci_write_config(struct file *filp, struct kobject *kobj,
6a91557
 	loff_t init_off = off;
6a91557
 	u8 *data = (u8 *) buf;
6a91557
 
6a91557
+	if (secure_modules())
6a91557
+		return -EPERM;
6a91557
+
6a91557
 	if (off > dev->cfg_size)
6a91557
 		return 0;
6a91557
 	if (off + count > dev->cfg_size) {
283bd06
@@ -1004,6 +1008,9 @@ static int pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr,
6a91557
 	resource_size_t start, end;
6a91557
 	int i;
6a91557
 
6a91557
+	if (secure_modules())
6a91557
+		return -EPERM;
6a91557
+
6a91557
 	for (i = 0; i < PCI_ROM_RESOURCE; i++)
6a91557
 		if (res == &pdev->resource[i])
6a91557
 			break;
283bd06
@@ -1105,6 +1112,9 @@ static ssize_t pci_write_resource_io(struct file *filp, struct kobject *kobj,
6a91557
 				     struct bin_attribute *attr, char *buf,
6a91557
 				     loff_t off, size_t count)
6a91557
 {
6a91557
+	if (secure_modules())
6a91557
+		return -EPERM;
6a91557
+
6a91557
 	return pci_resource_io(filp, kobj, attr, buf, off, count, true);
6a91557
 }
6a91557
 
6a91557
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c
6a91557
index 3f155e78513f..4265ea07e3b0 100644
6a91557
--- a/drivers/pci/proc.c
6a91557
+++ b/drivers/pci/proc.c
6a91557
@@ -116,6 +116,9 @@ static ssize_t proc_bus_pci_write(struct file *file, const char __user *buf,
6a91557
 	int size = dev->cfg_size;
6a91557
 	int cnt;
6a91557
 
6a91557
+	if (secure_modules())
6a91557
+		return -EPERM;
6a91557
+
6a91557
 	if (pos >= size)
6a91557
 		return 0;
6a91557
 	if (nbytes >= size)
6a91557
@@ -195,6 +198,9 @@ static long proc_bus_pci_ioctl(struct file *file, unsigned int cmd,
6a91557
 #endif /* HAVE_PCI_MMAP */
6a91557
 	int ret = 0;
6a91557
 
6a91557
+	if (secure_modules())
6a91557
+		return -EPERM;
6a91557
+
6a91557
 	switch (cmd) {
6a91557
 	case PCIIOC_CONTROLLER:
6a91557
 		ret = pci_domain_nr(dev->bus);
6a91557
@@ -233,7 +239,7 @@ static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma)
6a91557
 	struct pci_filp_private *fpriv = file->private_data;
6a91557
 	int i, ret;
6a91557
 
6a91557
-	if (!capable(CAP_SYS_RAWIO))
6a91557
+	if (!capable(CAP_SYS_RAWIO) || secure_modules())
6a91557
 		return -EPERM;
6a91557
 
6a91557
 	/* Make sure the caller is mapping a real resource for this device */
6a91557
diff --git a/drivers/pci/syscall.c b/drivers/pci/syscall.c
6a91557
index b91c4da68365..98f5637304d1 100644
6a91557
--- a/drivers/pci/syscall.c
6a91557
+++ b/drivers/pci/syscall.c
6a91557
@@ -10,6 +10,7 @@
6a91557
 #include <linux/errno.h>
6a91557
 #include <linux/pci.h>
6a91557
 #include <linux/syscalls.h>
6a91557
+#include <linux/module.h>
6a91557
 #include <asm/uaccess.h>
6a91557
 #include "pci.h"
6a91557
 
6a91557
@@ -92,7 +93,7 @@ SYSCALL_DEFINE5(pciconfig_write, unsigned long, bus, unsigned long, dfn,
6a91557
 	u32 dword;
6a91557
 	int err = 0;
6a91557
 
6a91557
-	if (!capable(CAP_SYS_ADMIN))
6a91557
+	if (!capable(CAP_SYS_ADMIN) || secure_modules())
6a91557
 		return -EPERM;
6a91557
 
6a91557
 	dev = pci_get_bus_and_slot(bus, dfn);
18c8249
-- 
18c8249
2.4.3
18c8249