[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [linux-2.6.18-xen] pciback: improve input validation
# HG changeset patch # User Jan Beulich <jbeulich@xxxxxxxx> # Date 1348566584 -7200 # Node ID 50245ed8527a266e614a233102b0994fc86f0151 # Parent 2e2f50c02c3c1b95c41f2e27b40b59b54fd246f2 pciback: improve input validation Reject - where this is not already being done elsewhere - out of range values originating from user mode. This goes as far as reasonably possible considering the non-conformance of the in-kernel sscanf(). At the same time, relax quirk parsing so that 0x prefixes get tolerated without unnecessarily limiting the range of values (in some cases using the prefix would make parsing outright fail no matter what value was intended to be specified) for the (future) case where the in-kernel sscanf() properly honors field width specifications even for integer conversions. Plus, to match parsing of standalone PCI device specifications, allow a second form of input not having a domain specified (implying domain 0). Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> --- diff -r 2e2f50c02c3c -r 50245ed8527a drivers/xen/pciback/pci_stub.c --- a/drivers/xen/pciback/pci_stub.c Tue Sep 25 11:48:19 2012 +0200 +++ b/drivers/xen/pciback/pci_stub.c Tue Sep 25 11:49:44 2012 +0200 @@ -121,7 +121,8 @@ static struct pcistub_device *pcistub_de if (psdev->dev != NULL && domain == pci_domain_nr(psdev->dev->bus) && bus == psdev->dev->bus->number - && PCI_DEVFN(slot, func) == psdev->dev->devfn) { + && slot == PCI_SLOT(psdev->dev->devfn) + && func == PCI_FUNC(psdev->dev->devfn)) { pcistub_device_get(psdev); goto out; } @@ -170,7 +171,8 @@ struct pci_dev *pcistub_get_pci_dev_by_s if (psdev->dev != NULL && domain == pci_domain_nr(psdev->dev->bus) && bus == psdev->dev->bus->number - && PCI_DEVFN(slot, func) == psdev->dev->devfn) { + && slot == PCI_SLOT(psdev->dev->devfn) + && func == PCI_FUNC(psdev->dev->devfn)) { found_dev = pcistub_device_get_pci_dev(pdev, psdev); break; } @@ -906,11 +908,18 @@ static inline int str_to_quirk(const cha { int err; - err = - sscanf(buf, " %04x:%02x:%02x.%1x-%08x:%1x:%08x", domain, bus, slot, - func, reg, size, mask); + err = sscanf(buf, " %x:%x:%x.%x-%x:%x:%x", domain, bus, slot, func, + reg, size, mask); if (err == 7) return 0; + + /* try again without domain */ + *domain = 0; + err = sscanf(buf, " %x:%x.%x-%x:%x:%x", bus, slot, func, reg, size, + mask); + if (err == 6) + return 0; + return -EINVAL; } @@ -918,7 +927,7 @@ static int pcistub_device_id_add(int dom { struct pcistub_device_id *pci_dev_id; unsigned long flags; - int rc = 0; + int rc = 0, devfn = PCI_DEVFN(slot, func); if (slot < 0) { for (slot = 0; !rc && slot < 32; ++slot) @@ -932,13 +941,23 @@ static int pcistub_device_id_add(int dom return rc; } +#ifdef CONFIG_PCI_DOMAINS + if (domain < 0 || domain > 0xffff +#else + if (domain +#endif + || bus < 0 || bus > 0xff + || PCI_SLOT(devfn) != slot + || PCI_FUNC(devfn) != func) + return -EINVAL; + pci_dev_id = kmalloc(sizeof(*pci_dev_id), GFP_KERNEL); if (!pci_dev_id) return -ENOMEM; pci_dev_id->domain = domain; pci_dev_id->bus = bus; - pci_dev_id->devfn = PCI_DEVFN(slot, func); + pci_dev_id->devfn = devfn; pr_debug("pciback: wants to seize %04x:%02x:%02x.%01x\n", domain, bus, slot, func); @@ -979,14 +998,18 @@ static int pcistub_device_id_remove(int return err; } -static int pcistub_reg_add(int domain, int bus, int slot, int func, int reg, - int size, int mask) +static int pcistub_reg_add(int domain, int bus, int slot, int func, + unsigned int reg, unsigned int size, + unsigned int mask) { int err = 0; struct pcistub_device *psdev; struct pci_dev *dev; struct config_field *field; + if (reg > 0xfff || (size < 4 && (mask >> (size * 8)))) + return -EINVAL; + psdev = pcistub_device_find(domain, bus, slot, func); if (!psdev) { err = -ENODEV; @@ -1149,13 +1172,11 @@ static ssize_t permissive_add(struct dev int err; struct pcistub_device *psdev; struct pciback_dev_data *dev_data; + err = str_to_slot(buf, &domain, &bus, &slot, &func); if (err) goto out; - if (slot < 0 || func < 0) { - err = -EINVAL; - goto out; - } + psdev = pcistub_device_find(domain, bus, slot, func); if (!psdev) { err = -ENODEV; _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |