ea38f2f
From 03a4ad09f20944e1917abfd24d1d0e5f107a2861 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
ea38f2f
Subject: [PATCH 02/20] PCI: Lock down BAR access when module security is
ea38f2f
 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
ea38f2f
index bcd10c795284..a950301496f3 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 */
86429d3
@@ -716,6 +717,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) {
86429d3
@@ -1007,6 +1011,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;
86429d3
@@ -1106,6 +1113,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
ea38f2f
index 2408abe4ee8c..59f321c56c18 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;
86429d3
 	int i, ret, write_combine;
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
ea38f2f
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
-- 
ea38f2f
2.9.3
18c8249