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