Prior to this patch we didn't make any attempt to prevent two entries in the array of interfaces/PCI devices from pointing to the same device. Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1002423 --- src/conf/network_conf.c | 33 ++++++++++++++++++++---- tests/networkxml2xmlin/hostdev-duplicate.xml | 11 ++++++++ tests/networkxml2xmlin/passthrough-duplicate.xml | 10 +++++++ tests/networkxml2xmltest.c | 2 ++ 4 files changed, 51 insertions(+), 5 deletions(-) create mode 100644 tests/networkxml2xmlin/hostdev-duplicate.xml create mode 100644 tests/networkxml2xmlin/passthrough-duplicate.xml diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c index 4fb2e2a..043c79b 100644 --- a/src/conf/network_conf.c +++ b/src/conf/network_conf.c @@ -1,7 +1,7 @@ /* * network_conf.c: network XML handling * - * Copyright (C) 2006-2015 Red Hat, Inc. + * Copyright (C) 2006-2016 Red Hat, Inc. * Copyright (C) 2006-2008 Daniel P. Berrange * * This library is free software; you can redistribute it and/or @@ -1799,7 +1799,7 @@ virNetworkForwardDefParseXML(const char *networkName, xmlXPathContextPtr ctxt, virNetworkForwardDefPtr def) { - size_t i; + size_t i, j; int ret = -1; xmlNodePtr *forwardIfNodes = NULL; xmlNodePtr *forwardPfNodes = NULL; @@ -1936,6 +1936,16 @@ virNetworkForwardDefParseXML(const char *networkName, continue; } + for (j = 0; j < i; j++) { + if (STREQ_NULLABLE(def->ifs[j].device.dev, forwardDev)) { + virReportError(VIR_ERR_XML_ERROR, + _("interface '%s' can only be " + "listed once in network %s"), + forwardDev, networkName); + goto cleanup; + } + } + def->ifs[i].device.dev = forwardDev; forwardDev = NULL; def->ifs[i].type = VIR_NETWORK_FORWARD_HOSTDEV_DEVICE_NETDEV; @@ -1963,12 +1973,25 @@ virNetworkForwardDefParseXML(const char *networkName, switch (def->ifs[i].type) { case VIR_NETWORK_FORWARD_HOSTDEV_DEVICE_PCI: - if (virDevicePCIAddressParseXML(forwardAddrNodes[i], - &def->ifs[i].device.pci) < 0) { + { + virDevicePCIAddressPtr addr = &def->ifs[i].device.pci; + + if (virDevicePCIAddressParseXML(forwardAddrNodes[i], addr) < 0) { goto cleanup; } + for (j = 0; j < i; j++) { + if (virDevicePCIAddressEqual(addr, &def->ifs[j].device.pci)) { + virReportError(VIR_ERR_XML_ERROR, + _("PCI device '%04x:%02x:%02x.%x' can " + "only be listed once in network %s"), + addr->domain, addr->bus, + addr->slot, addr->function, + networkName); + goto cleanup; + } + } break; - + } /* Add USB case here if we ever find a reason to support it */ default: diff --git a/tests/networkxml2xmlin/hostdev-duplicate.xml b/tests/networkxml2xmlin/hostdev-duplicate.xml new file mode 100644 index 0000000..79e55aa --- /dev/null +++ b/tests/networkxml2xmlin/hostdev-duplicate.xml @@ -0,0 +1,11 @@ +<network> + <name>hostdev</name> + <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid> + <forward mode='hostdev' managed='yes'> + <address type='pci' domain='0x0000' bus='0x03' slot='0x00' function='0x1'/> + <address type='pci' domain='0x0000' bus='0x03' slot='0x00' function='0x2'/> + <address type='pci' domain='0x0000' bus='0x03' slot='0x00' function='0x3'/> + <address type='pci' domain='0x0000' bus='0x03' slot='0x00' function='0x3'/> + <address type='pci' domain='0x0000' bus='0x03' slot='0x00' function='0x4'/> + </forward> +</network> diff --git a/tests/networkxml2xmlin/passthrough-duplicate.xml b/tests/networkxml2xmlin/passthrough-duplicate.xml new file mode 100644 index 0000000..8f645f7 --- /dev/null +++ b/tests/networkxml2xmlin/passthrough-duplicate.xml @@ -0,0 +1,10 @@ +<network> + <name>passthrough-duplicate</name> + <uuid>81ff0d90-c91e-6742-64da-4a736edb9a8b</uuid> + <forward mode="passthrough"> + <interface dev="eth1"/> + <interface dev="eth2"/> + <interface dev="eth3"/> + <interface dev="eth3"/> + </forward> +</network> diff --git a/tests/networkxml2xmltest.c b/tests/networkxml2xmltest.c index b83396b..eafd473 100644 --- a/tests/networkxml2xmltest.c +++ b/tests/networkxml2xmltest.c @@ -151,6 +151,8 @@ mymain(void) DO_TEST("passthrough-address-crash"); DO_TEST("nat-network-explicit-flood"); DO_TEST("host-bridge-no-flood"); + DO_TEST_PARSE_ERROR("hostdev-duplicate"); + DO_TEST_PARSE_ERROR("passthrough-duplicate"); return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; } -- 2.5.5 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list