diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 4ecc4e9ae6..8b270af6b6 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -606,7 +606,7 @@ networkBuildDnsmasqArgv(virNetworkObjPtr network,
* Needed to ensure dnsmasq uses same algorithm for processing
* multiple namedriver entries in /etc/resolv.conf as GLibC.
*/
- virCommandAddArgList(cmd, "--strict-order", "--bind-interfaces", NULL);
+ virCommandAddArg(cmd, "--strict-order");
if (network->def->domain)
virCommandAddArgPair(cmd, "--domain", network->def->domain);
@@ -621,9 +621,60 @@ networkBuildDnsmasqArgv(virNetworkObjPtr network,
/* *no* conf file */
virCommandAddArg(cmd, "--conf-file=");
- virCommandAddArgList(cmd,
- "--except-interface", "lo",
- NULL);
+ if (dnsmasqCapsGet(caps, DNSMASQ_CAPS_BIND_DYNAMIC)) {
+ /* using --bind-dynamic with only --interface (no
+ * --listen-address) prevents dnsmasq from responding to dns
+ * queries that arrive on some interface other than our bridge
+ * interface (in other words, requests originating somewhere
+ * other than one of the virtual guests connected directly to
+ * this network). This was added in response to CVE 2012-3411.
+ */
+ virCommandAddArgList(cmd,
+ "--bind-dynamic",
+ "--interface", network->def->bridge,
+ NULL);
+ } else {
+ virCommandAddArgList(cmd,
+ "--bind-interfaces",
+ "--except-interface", "lo",
+ NULL);
+ /*
+ * --interface does not actually work with dnsmasq < 2.47,
+ * due to DAD for ipv6 addresses on the interface.
+ *
+ * virCommandAddArgList(cmd, "--interface", network->def->bridge, NULL);
+ *
+ * So listen on all defined IPv[46] addresses
+ */
+ for (ii = 0;
+ (tmpipdef = virNetworkDefGetIpByIndex(network->def, AF_UNSPEC, ii));
+ ii++) {
+ char *ipaddr = virSocketAddrFormat(&tmpipdef->address);
+
+ if (!ipaddr)
+ goto cleanup;
+ /* also part of CVE 2012-3411 - if the host's version of
+ * dnsmasq doesn't have --bind-dynamic, only allow listening on
+ * private/local IP addresses (see RFC1918/RFC3484/RFC4193)
+ */
+ if (!virSocketAddrIsPrivate(&tmpipdef->address)) {
+ unsigned long version = dnsmasqCapsGetVersion(caps);
+
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Publicly routable address %s is prohibited. "
+ "The version of dnsmasq on this host (%d.%d) doesn't "
+ "support the --bind-dynamic option, which is required "
+ "for safe operation on a publicly routable subnet "
+ "(see CVE-2012-3411). You must either upgrade dnsmasq, "
+ "or use a private/local subnet range for this network "
+ "(as described in RFC1918/RFC3484/RFC4193)."), ipaddr,
+ (int)version / 1000000, (int)(version % 1000000) / 1000);
+ goto cleanup;
+ }
+ virCommandAddArgList(cmd, "--listen-address", ipaddr, NULL);
+ VIR_FREE(ipaddr);
+ }
+ }
/* If this is an isolated network, set the default route option
* (3) to be empty to avoid setting a default route that's
@@ -689,24 +740,6 @@ networkBuildDnsmasqArgv(virNetworkObjPtr network,
}
}
- /*
- * --interface does not actually work with dnsmasq < 2.47,
- * due to DAD for ipv6 addresses on the interface.
- *
- * virCommandAddArgList(cmd, "--interface", ipdef->bridge, NULL);
- *
- * So listen on all defined IPv[46] addresses
- */
- for (ii = 0;
- (tmpipdef = virNetworkDefGetIpByIndex(network->def, AF_UNSPEC, ii));
- ii++) {
- char *ipaddr = virSocketAddrFormat(&tmpipdef->address);
- if (!ipaddr)
- goto cleanup;
- virCommandAddArgList(cmd, "--listen-address", ipaddr, NULL);
- VIR_FREE(ipaddr);
- }
-
if (ipdef) {
for (r = 0 ; r < ipdef->nranges ; r++) {
char *saddr = virSocketAddrFormat(&ipdef->ranges[r].start);
diff --git a/tests/networkxml2argvdata/isolated-network.argv b/tests/networkxml2argvdata/isolated-network.argv
index 13e77b26a0..3d8601e686 100644
--- a/tests/networkxml2argvdata/isolated-network.argv
+++ b/tests/networkxml2argvdata/isolated-network.argv
@@ -1,7 +1,8 @@
-@DNSMASQ@ --strict-order --bind-interfaces \
+@DNSMASQ@ --strict-order \
--local=// --domain-needed --conf-file= \
---except-interface lo --dhcp-option=3 --no-resolv \
+--bind-interfaces --except-interface lo \
--listen-address 192.168.152.1 \
+--dhcp-option=3 --no-resolv \
--dhcp-range 192.168.152.2,192.168.152.254 \
--dhcp-leasefile=/var/lib/libvirt/dnsmasq/private.leases --dhcp-lease-max=253 \
--dhcp-no-override \
diff --git a/tests/networkxml2argvdata/nat-network-dns-hosts.argv b/tests/networkxml2argvdata/nat-network-dns-hosts.argv
index 03a0676935..e5143acbbe 100644
--- a/tests/networkxml2argvdata/nat-network-dns-hosts.argv
+++ b/tests/networkxml2argvdata/nat-network-dns-hosts.argv
@@ -1,4 +1,5 @@
-@DNSMASQ@ --strict-order --bind-interfaces --domain=example.com \
+@DNSMASQ@ --strict-order --domain=example.com \
--local=/example.com/ --domain-needed \
---conf-file= --except-interface lo --listen-address 192.168.122.1 \
+--conf-file= \
+--bind-dynamic --interface virbr0 \
--expand-hosts --addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts\
diff --git a/tests/networkxml2argvdata/nat-network-dns-srv-record-minimal.argv b/tests/networkxml2argvdata/nat-network-dns-srv-record-minimal.argv
index 210a60c01c..031da3fc3c 100644
--- a/tests/networkxml2argvdata/nat-network-dns-srv-record-minimal.argv
+++ b/tests/networkxml2argvdata/nat-network-dns-srv-record-minimal.argv
@@ -1,14 +1,13 @@
@DNSMASQ@ \
--strict-order \
---bind-interfaces \
--local=// --domain-needed --conf-file= \
---except-interface lo \
---srv-host=name.tcp.,,,, \
+--bind-interfaces --except-interface lo \
--listen-address 192.168.122.1 \
--listen-address 192.168.123.1 \
---listen-address 2001:db8:ac10:fe01::1 \
---listen-address 2001:db8:ac10:fd01::1 \
+--listen-address fc00:db8:ac10:fe01::1 \
+--listen-address fc00:db8:ac10:fd01::1 \
--listen-address 10.24.10.1 \
+--srv-host=name.tcp.,,,, \
--dhcp-range 192.168.122.2,192.168.122.254 \
--dhcp-leasefile=/var/lib/libvirt/dnsmasq/default.leases \
--dhcp-lease-max=253 \
diff --git a/tests/networkxml2argvdata/nat-network-dns-srv-record-minimal.xml b/tests/networkxml2argvdata/nat-network-dns-srv-record-minimal.xml
index e9b7680603..f6f24e1208 100644
--- a/tests/networkxml2argvdata/nat-network-dns-srv-record-minimal.xml
+++ b/tests/networkxml2argvdata/nat-network-dns-srv-record-minimal.xml
@@ -17,9 +17,9 @@
-
+
-
+
diff --git a/tests/networkxml2argvdata/nat-network-dns-srv-record.argv b/tests/networkxml2argvdata/nat-network-dns-srv-record.argv
index 833d3cd0f5..beff591a34 100644
--- a/tests/networkxml2argvdata/nat-network-dns-srv-record.argv
+++ b/tests/networkxml2argvdata/nat-network-dns-srv-record.argv
@@ -1,14 +1,8 @@
@DNSMASQ@ \
--strict-order \
---bind-interfaces \
--local=// --domain-needed --conf-file= \
---except-interface lo \
+--bind-dynamic --interface virbr0 \
--srv-host=name.tcp.test-domain-name,.,1024,10,10 \
---listen-address 192.168.122.1 \
---listen-address 192.168.123.1 \
---listen-address 2001:db8:ac10:fe01::1 \
---listen-address 2001:db8:ac10:fd01::1 \
---listen-address 10.24.10.1 \
--dhcp-range 192.168.122.2,192.168.122.254 \
--dhcp-leasefile=/var/lib/libvirt/dnsmasq/default.leases \
--dhcp-lease-max=253 \
diff --git a/tests/networkxml2argvdata/nat-network-dns-txt-record.argv b/tests/networkxml2argvdata/nat-network-dns-txt-record.argv
index 3481507791..fc164f6d78 100644
--- a/tests/networkxml2argvdata/nat-network-dns-txt-record.argv
+++ b/tests/networkxml2argvdata/nat-network-dns-txt-record.argv
@@ -1,9 +1,7 @@
-@DNSMASQ@ --strict-order --bind-interfaces \
+@DNSMASQ@ --strict-order \
--local=// --domain-needed --conf-file= \
---except-interface lo '--txt-record=example,example value' \
---listen-address 192.168.122.1 --listen-address 192.168.123.1 \
---listen-address 2001:db8:ac10:fe01::1 \
---listen-address 2001:db8:ac10:fd01::1 --listen-address 10.24.10.1 \
+--bind-dynamic --interface virbr0 \
+'--txt-record=example,example value' \
--dhcp-range 192.168.122.2,192.168.122.254 \
--dhcp-leasefile=/var/lib/libvirt/dnsmasq/default.leases \
--dhcp-lease-max=253 --dhcp-no-override \
diff --git a/tests/networkxml2argvdata/nat-network.argv b/tests/networkxml2argvdata/nat-network.argv
index 37fd2fca91..6303f76a1f 100644
--- a/tests/networkxml2argvdata/nat-network.argv
+++ b/tests/networkxml2argvdata/nat-network.argv
@@ -1,8 +1,6 @@
-@DNSMASQ@ --strict-order --bind-interfaces \
+@DNSMASQ@ --strict-order \
--local=// --domain-needed --conf-file= \
---except-interface lo --listen-address 192.168.122.1 \
---listen-address 192.168.123.1 --listen-address 2001:db8:ac10:fe01::1 \
---listen-address 2001:db8:ac10:fd01::1 --listen-address 10.24.10.1 \
+--bind-dynamic --interface virbr0 \
--dhcp-range 192.168.122.2,192.168.122.254 \
--dhcp-leasefile=/var/lib/libvirt/dnsmasq/default.leases \
--dhcp-lease-max=253 --dhcp-no-override \
diff --git a/tests/networkxml2argvdata/netboot-network.argv b/tests/networkxml2argvdata/netboot-network.argv
index 5408eb71c9..9699e5c8eb 100644
--- a/tests/networkxml2argvdata/netboot-network.argv
+++ b/tests/networkxml2argvdata/netboot-network.argv
@@ -1,6 +1,6 @@
-@DNSMASQ@ --strict-order --bind-interfaces --domain=example.com \
+@DNSMASQ@ --strict-order --domain=example.com \
--local=/example.com/ --domain-needed --conf-file= \
---except-interface lo --listen-address 192.168.122.1 \
+--bind-interfaces --except-interface lo --listen-address 192.168.122.1 \
--dhcp-range 192.168.122.2,192.168.122.254 \
--dhcp-leasefile=/var/lib/libvirt/dnsmasq/netboot.leases \
--dhcp-lease-max=253 --dhcp-no-override --expand-hosts \
diff --git a/tests/networkxml2argvdata/netboot-proxy-network.argv b/tests/networkxml2argvdata/netboot-proxy-network.argv
index 21e01e377f..9ac301832e 100644
--- a/tests/networkxml2argvdata/netboot-proxy-network.argv
+++ b/tests/networkxml2argvdata/netboot-proxy-network.argv
@@ -1,6 +1,7 @@
-@DNSMASQ@ --strict-order --bind-interfaces --domain=example.com \
+@DNSMASQ@ --strict-order --domain=example.com \
--local=/example.com/ --domain-needed --conf-file= \
---except-interface lo --listen-address 192.168.122.1 \
+--bind-interfaces --except-interface lo \
+--listen-address 192.168.122.1 \
--dhcp-range 192.168.122.2,192.168.122.254 \
--dhcp-leasefile=/var/lib/libvirt/dnsmasq/netboot.leases \
--dhcp-lease-max=253 --dhcp-no-override --expand-hosts \
diff --git a/tests/networkxml2argvdata/routed-network.argv b/tests/networkxml2argvdata/routed-network.argv
index 9fedb2b462..700c904a3f 100644
--- a/tests/networkxml2argvdata/routed-network.argv
+++ b/tests/networkxml2argvdata/routed-network.argv
@@ -1,4 +1,4 @@
-@DNSMASQ@ --strict-order --bind-interfaces \
+@DNSMASQ@ --strict-order \
--local=// --domain-needed --conf-file= \
---except-interface lo --listen-address 192.168.122.1 \
+--bind-dynamic --interface virbr1 \
--addn-hosts=/var/lib/libvirt/dnsmasq/local.addnhosts\