aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorJesse Barnes <jbarnes@virtuousgeek.org>2008-10-24 13:32:33 -0400
committerJesse Barnes <jbarnes@virtuousgeek.org>2009-01-07 14:12:20 -0500
commit9eff02e2042f96fb2aedd02e032eca1c5333d767 (patch)
tree677e78d73f420b69f06e839729e29c6e2a8720b5 /drivers/pci
parentede6f5aea054d3fb67c78857f7abdee602302043 (diff)
PCI: check mmap range of /proc/bus/pci files too
/proc/bus/pci allows you to mmap resource ranges too, so we should probably be checking to make sure the mapping is somewhat valid. Uses the same code as the recent sysfs mmap range checking patch from Linus. Acked-by: David Miller <davem@davemloft.net> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/pci-sysfs.c2
-rw-r--r--drivers/pci/pci.h4
-rw-r--r--drivers/pci/proc.c11
3 files changed, 15 insertions, 2 deletions
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index c88485860a0a..388440e0d222 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -569,7 +569,7 @@ void pci_remove_legacy_files(struct pci_bus *b)
569 569
570#ifdef HAVE_PCI_MMAP 570#ifdef HAVE_PCI_MMAP
571 571
572static int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vma) 572int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vma)
573{ 573{
574 unsigned long nr, start, size; 574 unsigned long nr, start, size;
575 575
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 9de87e9f98f5..d3e65e29df51 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -10,6 +10,10 @@ extern int pci_uevent(struct device *dev, struct kobj_uevent_env *env);
10extern int pci_create_sysfs_dev_files(struct pci_dev *pdev); 10extern int pci_create_sysfs_dev_files(struct pci_dev *pdev);
11extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev); 11extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev);
12extern void pci_cleanup_rom(struct pci_dev *dev); 12extern void pci_cleanup_rom(struct pci_dev *dev);
13#ifdef HAVE_PCI_MMAP
14extern int pci_mmap_fits(struct pci_dev *pdev, int resno,
15 struct vm_area_struct *vma);
16#endif
13 17
14/** 18/**
15 * Firmware PM callbacks 19 * Firmware PM callbacks
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c
index e1098c302c45..7fb086d39617 100644
--- a/drivers/pci/proc.c
+++ b/drivers/pci/proc.c
@@ -252,11 +252,20 @@ static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma)
252 const struct proc_dir_entry *dp = PDE(inode); 252 const struct proc_dir_entry *dp = PDE(inode);
253 struct pci_dev *dev = dp->data; 253 struct pci_dev *dev = dp->data;
254 struct pci_filp_private *fpriv = file->private_data; 254 struct pci_filp_private *fpriv = file->private_data;
255 int ret; 255 int i, ret;
256 256
257 if (!capable(CAP_SYS_RAWIO)) 257 if (!capable(CAP_SYS_RAWIO))
258 return -EPERM; 258 return -EPERM;
259 259
260 /* Make sure the caller is mapping a real resource for this device */
261 for (i = 0; i < PCI_ROM_RESOURCE; i++) {
262 if (pci_mmap_fits(dev, i, vma))
263 break;
264 }
265
266 if (i >= PCI_ROM_RESOURCE)
267 return -ENODEV;
268
260 ret = pci_mmap_page_range(dev, vma, 269 ret = pci_mmap_page_range(dev, vma,
261 fpriv->mmap_state, 270 fpriv->mmap_state,
262 fpriv->write_combine); 271 fpriv->write_combine);