aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/xen
diff options
context:
space:
mode:
authorJan Beulich <JBeulich@suse.com>2012-11-02 10:36:38 -0400
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2012-11-02 11:04:02 -0400
commit5b71fbdc64225b7a86944f4f0de80e59071187c7 (patch)
tree4a3ea77d3a531194d55156252aa12e430132be0a /drivers/xen
parent9d02b43dee0d7fb18dfb13a00915550b1a3daa9f (diff)
xen-pciback: simplify and tighten parsing of device IDs
Now that at least one of the conformance problems of the kernel's sscanf() was addressed (commit da99075c1d368315e1508b6143226c0d27b621e0), we can improve the parsing done in xen-pciback both in terms of code readability and correctness (in particular properly rejecting input strings not well formed). 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.c83
1 files changed, 39 insertions, 44 deletions
diff --git a/drivers/xen/xen-pciback/pci_stub.c b/drivers/xen/xen-pciback/pci_stub.c
index 961d664e2d2f..1a92739f4318 100644
--- a/drivers/xen/xen-pciback/pci_stub.c
+++ b/drivers/xen/xen-pciback/pci_stub.c
@@ -897,42 +897,35 @@ static struct pci_driver xen_pcibk_pci_driver = {
897static inline int str_to_slot(const char *buf, int *domain, int *bus, 897static inline int str_to_slot(const char *buf, int *domain, int *bus,
898 int *slot, int *func) 898 int *slot, int *func)
899{ 899{
900 int err; 900 int parsed = 0;
901 char wc = '*';
902 901
903 err = sscanf(buf, " %x:%x:%x.%x", domain, bus, slot, func); 902 switch (sscanf(buf, " %x:%x:%x.%x %n", domain, bus, slot, func,
904 switch (err) { 903 &parsed)) {
905 case 3: 904 case 3:
906 *func = -1; 905 *func = -1;
907 err = sscanf(buf, " %x:%x:%x.%c", domain, bus, slot, &wc); 906 sscanf(buf, " %x:%x:%x.* %n", domain, bus, slot, &parsed);
908 break; 907 break;
909 case 2: 908 case 2:
910 *slot = *func = -1; 909 *slot = *func = -1;
911 err = sscanf(buf, " %x:%x:*.%c", domain, bus, &wc); 910 sscanf(buf, " %x:%x:*.* %n", domain, bus, &parsed);
912 if (err >= 2)
913 ++err;
914 break; 911 break;
915 } 912 }
916 if (err == 4 && wc == '*') 913 if (parsed && !buf[parsed])
917 return 0; 914 return 0;
918 else if (err < 0)
919 return -EINVAL;
920 915
921 /* try again without domain */ 916 /* try again without domain */
922 *domain = 0; 917 *domain = 0;
923 wc = '*'; 918 switch (sscanf(buf, " %x:%x.%x %n", bus, slot, func, &parsed)) {
924 err = sscanf(buf, " %x:%x.%x", bus, slot, func);
925 switch (err) {
926 case 2: 919 case 2:
927 *func = -1; 920 *func = -1;
928 err = sscanf(buf, " %x:%x.%c", bus, slot, &wc); 921 sscanf(buf, " %x:%x.* %n", bus, slot, &parsed);
929 break; 922 break;
930 case 1: 923 case 1:
931 *slot = *func = -1; 924 *slot = *func = -1;
932 err = sscanf(buf, " %x:*.%c", bus, &wc) + 1; 925 sscanf(buf, " %x:*.* %n", bus, &parsed);
933 break; 926 break;
934 } 927 }
935 if (err == 3 && wc == '*') 928 if (parsed && !buf[parsed])
936 return 0; 929 return 0;
937 930
938 return -EINVAL; 931 return -EINVAL;
@@ -941,13 +934,20 @@ static inline int str_to_slot(const char *buf, int *domain, int *bus,
941static inline int str_to_quirk(const char *buf, int *domain, int *bus, int 934static inline int str_to_quirk(const char *buf, int *domain, int *bus, int
942 *slot, int *func, int *reg, int *size, int *mask) 935 *slot, int *func, int *reg, int *size, int *mask)
943{ 936{
944 int err; 937 int parsed = 0;
938
939 sscanf(buf, " %4x:%2x:%2x.%d-%8x:%1x:%8x %n", domain, bus, slot, func,
940 reg, size, mask, &parsed);
941 if (parsed && !buf[parsed])
942 return 0;
945 943
946 err = 944 /* try again without domain */
947 sscanf(buf, " %04x:%02x:%02x.%d-%08x:%1x:%08x", domain, bus, slot, 945 *domain = 0;
948 func, reg, size, mask); 946 sscanf(buf, " %2x:%2x.%d-%8x:%1x:%8x %n", bus, slot, func, reg, size,
949 if (err == 7) 947 mask, &parsed);
948 if (parsed && !buf[parsed])
950 return 0; 949 return 0;
950
951 return -EINVAL; 951 return -EINVAL;
952} 952}
953 953
@@ -1339,8 +1339,6 @@ static int __init pcistub_init(void)
1339 1339
1340 if (pci_devs_to_hide && *pci_devs_to_hide) { 1340 if (pci_devs_to_hide && *pci_devs_to_hide) {
1341 do { 1341 do {
1342 char wc = '*';
1343
1344 parsed = 0; 1342 parsed = 0;
1345 1343
1346 err = sscanf(pci_devs_to_hide + pos, 1344 err = sscanf(pci_devs_to_hide + pos,
@@ -1349,51 +1347,48 @@ static int __init pcistub_init(void)
1349 switch (err) { 1347 switch (err) {
1350 case 3: 1348 case 3:
1351 func = -1; 1349 func = -1;
1352 err = sscanf(pci_devs_to_hide + pos, 1350 sscanf(pci_devs_to_hide + pos,
1353 " (%x:%x:%x.%c) %n", 1351 " (%x:%x:%x.*) %n",
1354 &domain, &bus, &slot, &wc, 1352 &domain, &bus, &slot, &parsed);
1355 &parsed);
1356 break; 1353 break;
1357 case 2: 1354 case 2:
1358 slot = func = -1; 1355 slot = func = -1;
1359 err = sscanf(pci_devs_to_hide + pos, 1356 sscanf(pci_devs_to_hide + pos,
1360 " (%x:%x:*.%c) %n", 1357 " (%x:%x:*.*) %n",
1361 &domain, &bus, &wc, &parsed) + 1; 1358 &domain, &bus, &parsed);
1362 break; 1359 break;
1363 } 1360 }
1364 1361
1365 if (err != 4 || wc != '*') { 1362 if (!parsed) {
1366 domain = 0; 1363 domain = 0;
1367 wc = '*';
1368 err = sscanf(pci_devs_to_hide + pos, 1364 err = sscanf(pci_devs_to_hide + pos,
1369 " (%x:%x.%x) %n", 1365 " (%x:%x.%x) %n",
1370 &bus, &slot, &func, &parsed); 1366 &bus, &slot, &func, &parsed);
1371 switch (err) { 1367 switch (err) {
1372 case 2: 1368 case 2:
1373 func = -1; 1369 func = -1;
1374 err = sscanf(pci_devs_to_hide + pos, 1370 sscanf(pci_devs_to_hide + pos,
1375 " (%x:%x.%c) %n", 1371 " (%x:%x.*) %n",
1376 &bus, &slot, &wc, 1372 &bus, &slot, &parsed);
1377 &parsed);
1378 break; 1373 break;
1379 case 1: 1374 case 1:
1380 slot = func = -1; 1375 slot = func = -1;
1381 err = sscanf(pci_devs_to_hide + pos, 1376 sscanf(pci_devs_to_hide + pos,
1382 " (%x:*.%c) %n", 1377 " (%x:*.*) %n",
1383 &bus, &wc, &parsed) + 1; 1378 &bus, &parsed);
1384 break; 1379 break;
1385 } 1380 }
1386 if (err != 3 || wc != '*')
1387 goto parse_error;
1388 } 1381 }
1389 1382
1383 if (parsed <= 0)
1384 goto parse_error;
1385
1390 err = pcistub_device_id_add(domain, bus, slot, func); 1386 err = pcistub_device_id_add(domain, bus, slot, func);
1391 if (err) 1387 if (err)
1392 goto out; 1388 goto out;
1393 1389
1394 /* if parsed<=0, we've reached the end of the string */
1395 pos += parsed; 1390 pos += parsed;
1396 } while (parsed > 0 && pci_devs_to_hide[pos]); 1391 } while (pci_devs_to_hide[pos]);
1397 } 1392 }
1398 1393
1399 /* If we're the first PCI Device Driver to register, we're the 1394 /* If we're the first PCI Device Driver to register, we're the