aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/xen
diff options
context:
space:
mode:
authorJan Beulich <JBeulich@suse.com>2012-11-02 10:37:13 -0400
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2012-11-02 11:04:03 -0400
commitb3e40b72bb24237b0aee9f6ba2e9f88dd4ff3c0a (patch)
tree67b38a9e693d4af602b1c05e867c0487c5fc9cf5 /drivers/xen
parent5b71fbdc64225b7a86944f4f0de80e59071187c7 (diff)
xen-pciback: reject out of range inputs
This add checks for out of range numbers (including in cases where the folding of slot and function into a single value could yield false matches). It also removes the bogus field width restrictions in str_to_quirk() - nowhere else in the driver this is being done, and hence this function could reject input the equivalent of which would be happily accepted in other places (in particular, "0x" prefixes causing the effective width of the actual number to be either zero or less than what would be required to cover the full range of valid values). Note that for the moment this second part is cosmetic only, as the kernel's sscanf() currently ignores the field widths, but a patch to overcome this is on its way. Signed-off-by: Jan Beulich <jbeulich@suse.com> Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Diffstat (limited to 'drivers/xen')
-rw-r--r--drivers/xen/xen-pciback/pci_stub.c39
1 files changed, 27 insertions, 12 deletions
diff --git a/drivers/xen/xen-pciback/pci_stub.c b/drivers/xen/xen-pciback/pci_stub.c
index 1a92739f431..129e1674f4a 100644
--- a/drivers/xen/xen-pciback/pci_stub.c
+++ b/drivers/xen/xen-pciback/pci_stub.c
@@ -142,7 +142,8 @@ static struct pcistub_device *pcistub_device_find(int domain, int bus,
142 if (psdev->dev != NULL 142 if (psdev->dev != NULL
143 && domain == pci_domain_nr(psdev->dev->bus) 143 && domain == pci_domain_nr(psdev->dev->bus)
144 && bus == psdev->dev->bus->number 144 && bus == psdev->dev->bus->number
145 && PCI_DEVFN(slot, func) == psdev->dev->devfn) { 145 && slot == PCI_SLOT(psdev->dev->devfn)
146 && func == PCI_FUNC(psdev->dev->devfn)) {
146 pcistub_device_get(psdev); 147 pcistub_device_get(psdev);
147 goto out; 148 goto out;
148 } 149 }
@@ -191,7 +192,8 @@ struct pci_dev *pcistub_get_pci_dev_by_slot(struct xen_pcibk_device *pdev,
191 if (psdev->dev != NULL 192 if (psdev->dev != NULL
192 && domain == pci_domain_nr(psdev->dev->bus) 193 && domain == pci_domain_nr(psdev->dev->bus)
193 && bus == psdev->dev->bus->number 194 && bus == psdev->dev->bus->number
194 && PCI_DEVFN(slot, func) == psdev->dev->devfn) { 195 && slot == PCI_SLOT(psdev->dev->devfn)
196 && func == PCI_FUNC(psdev->dev->devfn)) {
195 found_dev = pcistub_device_get_pci_dev(pdev, psdev); 197 found_dev = pcistub_device_get_pci_dev(pdev, psdev);
196 break; 198 break;
197 } 199 }
@@ -936,14 +938,14 @@ static inline int str_to_quirk(const char *buf, int *domain, int *bus, int
936{ 938{
937 int parsed = 0; 939 int parsed = 0;
938 940
939 sscanf(buf, " %4x:%2x:%2x.%d-%8x:%1x:%8x %n", domain, bus, slot, func, 941 sscanf(buf, " %x:%x:%x.%x-%x:%x:%x %n", domain, bus, slot, func,
940 reg, size, mask, &parsed); 942 reg, size, mask, &parsed);
941 if (parsed && !buf[parsed]) 943 if (parsed && !buf[parsed])
942 return 0; 944 return 0;
943 945
944 /* try again without domain */ 946 /* try again without domain */
945 *domain = 0; 947 *domain = 0;
946 sscanf(buf, " %2x:%2x.%d-%8x:%1x:%8x %n", bus, slot, func, reg, size, 948 sscanf(buf, " %x:%x.%x-%x:%x:%x %n", bus, slot, func, reg, size,
947 mask, &parsed); 949 mask, &parsed);
948 if (parsed && !buf[parsed]) 950 if (parsed && !buf[parsed])
949 return 0; 951 return 0;
@@ -955,7 +957,7 @@ static int pcistub_device_id_add(int domain, int bus, int slot, int func)
955{ 957{
956 struct pcistub_device_id *pci_dev_id; 958 struct pcistub_device_id *pci_dev_id;
957 unsigned long flags; 959 unsigned long flags;
958 int rc = 0; 960 int rc = 0, devfn = PCI_DEVFN(slot, func);
959 961
960 if (slot < 0) { 962 if (slot < 0) {
961 for (slot = 0; !rc && slot < 32; ++slot) 963 for (slot = 0; !rc && slot < 32; ++slot)
@@ -969,13 +971,24 @@ static int pcistub_device_id_add(int domain, int bus, int slot, int func)
969 return rc; 971 return rc;
970 } 972 }
971 973
974 if ((
975#if !defined(MODULE) /* pci_domains_supported is not being exported */ \
976 || !defined(CONFIG_PCI_DOMAINS)
977 !pci_domains_supported ? domain :
978#endif
979 domain < 0 || domain > 0xffff)
980 || bus < 0 || bus > 0xff
981 || PCI_SLOT(devfn) != slot
982 || PCI_FUNC(devfn) != func)
983 return -EINVAL;
984
972 pci_dev_id = kmalloc(sizeof(*pci_dev_id), GFP_KERNEL); 985 pci_dev_id = kmalloc(sizeof(*pci_dev_id), GFP_KERNEL);
973 if (!pci_dev_id) 986 if (!pci_dev_id)
974 return -ENOMEM; 987 return -ENOMEM;
975 988
976 pci_dev_id->domain = domain; 989 pci_dev_id->domain = domain;
977 pci_dev_id->bus = bus; 990 pci_dev_id->bus = bus;
978 pci_dev_id->devfn = PCI_DEVFN(slot, func); 991 pci_dev_id->devfn = devfn;
979 992
980 pr_debug(DRV_NAME ": wants to seize %04x:%02x:%02x.%d\n", 993 pr_debug(DRV_NAME ": wants to seize %04x:%02x:%02x.%d\n",
981 domain, bus, slot, func); 994 domain, bus, slot, func);
@@ -1016,14 +1029,18 @@ static int pcistub_device_id_remove(int domain, int bus, int slot, int func)
1016 return err; 1029 return err;
1017} 1030}
1018 1031
1019static int pcistub_reg_add(int domain, int bus, int slot, int func, int reg, 1032static int pcistub_reg_add(int domain, int bus, int slot, int func,
1020 int size, int mask) 1033 unsigned int reg, unsigned int size,
1034 unsigned int mask)
1021{ 1035{
1022 int err = 0; 1036 int err = 0;
1023 struct pcistub_device *psdev; 1037 struct pcistub_device *psdev;
1024 struct pci_dev *dev; 1038 struct pci_dev *dev;
1025 struct config_field *field; 1039 struct config_field *field;
1026 1040
1041 if (reg > 0xfff || (size < 4 && (mask >> (size * 8))))
1042 return -EINVAL;
1043
1027 psdev = pcistub_device_find(domain, bus, slot, func); 1044 psdev = pcistub_device_find(domain, bus, slot, func);
1028 if (!psdev) { 1045 if (!psdev) {
1029 err = -ENODEV; 1046 err = -ENODEV;
@@ -1254,13 +1271,11 @@ static ssize_t permissive_add(struct device_driver *drv, const char *buf,
1254 int err; 1271 int err;
1255 struct pcistub_device *psdev; 1272 struct pcistub_device *psdev;
1256 struct xen_pcibk_dev_data *dev_data; 1273 struct xen_pcibk_dev_data *dev_data;
1274
1257 err = str_to_slot(buf, &domain, &bus, &slot, &func); 1275 err = str_to_slot(buf, &domain, &bus, &slot, &func);
1258 if (err) 1276 if (err)
1259 goto out; 1277 goto out;
1260 if (slot < 0 || func < 0) { 1278
1261 err = -EINVAL;
1262 goto out;
1263 }
1264 psdev = pcistub_device_find(domain, bus, slot, func); 1279 psdev = pcistub_device_find(domain, bus, slot, func);
1265 if (!psdev) { 1280 if (!psdev) {
1266 err = -ENODEV; 1281 err = -ENODEV;