Commit 9eff02e2 authored by Jesse Barnes's avatar Jesse Barnes

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: default avatarDavid Miller <davem@davemloft.net>
Signed-off-by: default avatarJesse Barnes <jbarnes@virtuousgeek.org>
parent ede6f5ae
...@@ -569,7 +569,7 @@ void pci_remove_legacy_files(struct pci_bus *b) ...@@ -569,7 +569,7 @@ void pci_remove_legacy_files(struct pci_bus *b)
#ifdef HAVE_PCI_MMAP #ifdef HAVE_PCI_MMAP
static int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vma) int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vma)
{ {
unsigned long nr, start, size; unsigned long nr, start, size;
......
...@@ -10,6 +10,10 @@ extern int pci_uevent(struct device *dev, struct kobj_uevent_env *env); ...@@ -10,6 +10,10 @@ extern int pci_uevent(struct device *dev, struct kobj_uevent_env *env);
extern int pci_create_sysfs_dev_files(struct pci_dev *pdev); extern int pci_create_sysfs_dev_files(struct pci_dev *pdev);
extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev); extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev);
extern void pci_cleanup_rom(struct pci_dev *dev); extern void pci_cleanup_rom(struct pci_dev *dev);
#ifdef HAVE_PCI_MMAP
extern int pci_mmap_fits(struct pci_dev *pdev, int resno,
struct vm_area_struct *vma);
#endif
/** /**
* Firmware PM callbacks * Firmware PM callbacks
......
...@@ -252,11 +252,20 @@ static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma) ...@@ -252,11 +252,20 @@ static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma)
const struct proc_dir_entry *dp = PDE(inode); const struct proc_dir_entry *dp = PDE(inode);
struct pci_dev *dev = dp->data; struct pci_dev *dev = dp->data;
struct pci_filp_private *fpriv = file->private_data; struct pci_filp_private *fpriv = file->private_data;
int ret; int i, ret;
if (!capable(CAP_SYS_RAWIO)) if (!capable(CAP_SYS_RAWIO))
return -EPERM; return -EPERM;
/* Make sure the caller is mapping a real resource for this device */
for (i = 0; i < PCI_ROM_RESOURCE; i++) {
if (pci_mmap_fits(dev, i, vma))
break;
}
if (i >= PCI_ROM_RESOURCE)
return -ENODEV;
ret = pci_mmap_page_range(dev, vma, ret = pci_mmap_page_range(dev, vma,
fpriv->mmap_state, fpriv->mmap_state,
fpriv->write_combine); fpriv->write_combine);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment