Bug 833033 (CVE-2012-3411) - CVE-2012-3411 libvirt+dnsmasq: DNS configured to answer DNS queries from non-virtual networks
Summary: CVE-2012-3411 libvirt+dnsmasq: DNS configured to answer DNS queries from non-...
Keywords:
Status: CLOSED ERRATA
Alias: CVE-2012-3411
Product: Security Response
Classification: Other
Component: vulnerability
Version: unspecified
Hardware: Unspecified
OS: Unspecified
medium
medium
Target Milestone: ---
Assignee: Red Hat Product Security
QA Contact:
URL:
Whiteboard:
Depends On: 838528 882251
Blocks: 838539
TreeView+ depends on / blocked
 
Reported: 2012-06-18 12:31 UTC by David Woodhouse
Modified: 2021-02-23 14:31 UTC (History)
21 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
: 874702 (view as bug list)
Environment:
Last Closed: 2015-02-26 22:57:49 UTC
Embargoed:


Attachments (Terms of Use)
Use SO_BINDTODEVICE in make_sock() (3.04 KB, patch)
2012-06-18 12:59 UTC, David Woodhouse
no flags Details | Diff
Commit from upstream git (tag v2.63test1) for reference (14.90 KB, patch)
2012-11-08 10:05 UTC, Tomáš Hozza
no flags Details | Diff


Links
System ID Private Priority Status Summary Last Updated
Red Hat Product Errata RHSA-2013:0277 0 normal SHIPPED_LIVE Moderate: dnsmasq security, bug fix and enhancement update 2013-02-20 21:28:47 UTC
Red Hat Product Errata RHSA-2013:0579 0 normal SHIPPED_LIVE Important: rhev-hypervisor6 security, bug fix, and enhancement update 2013-02-28 23:55:03 UTC

Description David Woodhouse 2012-06-18 12:31:40 UTC
I just found my home ADSL line under "attack" with a constant stream of spoofed DNS queries which produce large results, such as 'ANY' requests for 'ripe.net'.

I was surprised to find that my machine was actually *responding* to these queries.

I have libvirt configured to give a range of public IP addresses to its guests. The target of the attack was the host's IP address on that subnet, 81.187.2.161.

It seems that your dnsmasq instance is listening on that address, but *not* correctly discarding packets which come from a different interface. Even though the --bind-interface option is set.
This is the command line:

/sbin/dnsmasq --strict-order --bind-interfaces --pid-file=/var/run/libvirt/network/net3.pid --conf-file= --except-interface lo --listen-address 81.187.2.161 --dhcp-range 81.187.2.168,81.187.2.174 --dhcp-leasefile=/var/lib/libvirt/dnsmasq/net3.leases --dhcp-lease-max=7 --dhcp-no-override


I tried using '--interface virbr1' instead of '--except-interface lo', but it still seemed to answer external queries:

/sbin/dnsmasq --strict-order --bind-interfaces --pid-file=/var/run/libvirt/network/net3.pid --conf-file= --interface virbr1 --listen-address 81.187.2.161 --dhcp-range 81.187.2.168,81.187.2.174 --dhcp-leasefile=/var/lib/libvirt/dnsmasq/net3.leases --dhcp-lease-max=7 --dhcp-no-override

Comment 1 Daniel Berrangé 2012-06-18 12:50:21 UTC
Can you provide a bit more information about your host/libvirt setup, so I can make sure I understand your scenario correctly:

 - The output of 'virsh net-dumpxml YOUR-GUEST-NET'
 - The output of 'brctl show'
 - The output of 'iptables -L -n -v'
 - The output of 'ip addr show'
 - The output of 'ip route show'

Comment 2 Daniel Berrangé 2012-06-18 12:51:48 UTC
Making the BZ private to the reporter + Red Hat eng to avoid publicising reporter's network info

Comment 3 Daniel Berrangé 2012-06-18 12:57:34 UTC
We presume that the host has a firewall configured with a REJECT policy on the INPUT chain by default (eg the standard Fedora/RHEL iptables config, or an equivalent home-grown setup). We then allow access to port 53 for traffic originating on the bridge device associated with the libvirt network, eg 'virbr0' in this case:

Chain INPUT (policy REJECT 50 packets, 32325 bytes)
 pkts bytes target     prot opt in     out     source               destination         
  [snip]
    0     0 ACCEPT     udp  --  virbr0 *       0.0.0.0/0            0.0.0.0/0            udp dpt:53
    0     0 ACCEPT     tcp  --  virbr0 *       0.0.0.0/0            0.0.0.0/0            tcp dpt:53

since the physical ethernet device is not enslaved in this bridge, it ought not to be possible for traffic originating on the public ethernet device to reach the dnsmasq server.

Comment 4 David Woodhouse 2012-06-18 12:59:10 UTC
Created attachment 592634 [details]
Use SO_BINDTODEVICE in make_sock()

Turns out it wasn't the command line at fault; it's dnsmasq itself. This patch "fixes" it, although upon going to clean it up to make it more acceptable for upstream inclusion, I noticed there was *already* some attempt at using SO_BINDTODEVICE which apparently wasn't working.

Comment 5 David Woodhouse 2012-06-18 13:04:43 UTC
No need to by coy about my IP addresses. The IP address on which your software was running an open DNS relay (☺) has already been discovered by the bad guys, and was being used as part of a DDoS attack. I've had the ISP block it at their end, for now.

The setup is really simple. I had a range of IP addresses which were unused, so I configured my local router to route them to my laptop (81.187.2.160/28 via 90.155.92.197 dev eth0, on the router). On the laptop, I then configured virbr1 to use those IP addresses:

# virsh net-dumpxml net3
<network>
  <name>net3</name>
  <uuid>04a0a385-118d-d629-ead2-1c8d60ca9b99</uuid>
  <forward dev='wlan0' mode='route'>
    <interface dev='wlan0'/>
  </forward>
  <bridge name='virbr1' stp='on' delay='0' />
  <mac address='52:54:00:18:BE:1A'/>
  <ip address='81.187.2.161' netmask='255.255.255.240'>
    <dhcp>
      <range start='81.187.2.168' end='81.187.2.174' />
    </dhcp>
  </ip>
</network>

# ip route
default via 90.155.92.214 dev wlan0  proto static 
81.187.2.160/28 dev virbr1  proto kernel  scope link  src 81.187.2.161 
90.155.92.192/26 dev wlan0  proto kernel  scope link  src 90.155.92.197 
192.168.100.0/24 dev virbr2  proto kernel  scope link  src 192.168.100.1 
192.168.122.0/24 dev virbr0  proto kernel  scope link  src 192.168.122.1 

# brctl show
bridge name	bridge id		STP enabled	interfaces
virbr0		8000.525400574759	yes		virbr0-nic
virbr1		8000.52540018be1a	yes		virbr1-nic
							vnet0
virbr2		8000.525400d0faf4	yes		virbr2-nic

# ip addr 
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN qlen 1000
    link/ether c8:2a:14:42:60:a8 brd ff:ff:ff:ff:ff:ff
3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1001
    link/ether e4:ce:8f:1f:f2:c0 brd ff:ff:ff:ff:ff:ff
    inet 90.155.92.197/26 brd 90.155.92.255 scope global wlan0
    inet6 2001:8b0:10b:1:e6ce:8fff:fe1f:f2c0/64 scope global dynamic 
       valid_lft 294sec preferred_lft 114sec
    inet6 fe80::e6ce:8fff:fe1f:f2c0/64 scope link 
       valid_lft forever preferred_lft forever
4: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN 
    link/ether 52:54:00:57:47:59 brd ff:ff:ff:ff:ff:ff
    inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
5: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc noop master virbr0 state DOWN qlen 500
    link/ether 52:54:00:57:47:59 brd ff:ff:ff:ff:ff:ff
6: virbr1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP 
    link/ether 52:54:00:18:be:1a brd ff:ff:ff:ff:ff:ff
    inet 81.187.2.161/28 brd 81.187.2.175 scope global virbr1
7: virbr1-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc noop master virbr1 state DOWN qlen 500
    link/ether 52:54:00:18:be:1a brd ff:ff:ff:ff:ff:ff
8: virbr2: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN 
    link/ether 52:54:00:d0:fa:f4 brd ff:ff:ff:ff:ff:ff
    inet 192.168.100.1/24 brd 192.168.100.255 scope global virbr2
9: virbr2-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc noop master virbr2 state DOWN qlen 500
    link/ether 52:54:00:d0:fa:f4 brd ff:ff:ff:ff:ff:ff
47: vnet0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master virbr1 state UNKNOWN qlen 500
    link/ether fe:54:00:6c:8d:51 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::fc54:ff:fe6c:8d51/64 scope link 
       valid_lft forever preferred_lft forever

Comment 6 Daniel Berrangé 2012-06-18 13:15:41 UTC
Ah to the traffic to dnsmasq was arriving via wlan0 (90.155.92.197/26) and FORWARDED to virbr1 (81.187.2.161/28) so IIUC, it /would/ match the iptables rules we provided for port 53.

I wonder if we should add in an extra iptables rule to block traffic on port 53, with a physdev match against the NIC listed in  <forward dev='wlan0' mode='route'>. This ought to ensure only traffic coming from VMs can access the DNS server.

Comment 7 David Woodhouse 2012-06-18 13:25:24 UTC
(In reply to comment #3)
> We presume that the host has a firewall configured with a REJECT policy on
> the INPUT chain by default (eg the standard Fedora/RHEL iptables config, or
> an equivalent home-grown setup)

The assumption is not valid in the general case. The REJECT policy was not appropriate here, and was changed. 

The REJECT policy is just the *default* for Fedora; it's not *mandatory*, so we really mustn't ship packages which depend on it.

A firewall is a band-aid for broken software. In an ideal world, you should never need it; the software *itself* should behave correctly (as dnsmasq does after my patch). The firewall is an *extra* line of defence.

If you start to *depend* on the firewall, and use it as an excuse for not designing things to be secure in themselves, then the benefit effect is lost.

You no longer *have* a second line of defence; you're back down to *one* line of defence. And now it's not even closely tied to your software — it's outside your control and much harder to be sure of.

We block stuff with a firewall in *addition* to making it secure. Not *instead*.

Comment 8 David Woodhouse 2012-06-18 13:26:16 UTC
$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     udp  --  anywhere             anywhere             udp dpt:domain
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:domain
ACCEPT     udp  --  anywhere             anywhere             udp dpt:bootps
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:bootps
ACCEPT     udp  --  anywhere             anywhere             udp dpt:domain
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:domain
ACCEPT     udp  --  anywhere             anywhere             udp dpt:bootps
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:bootps
ACCEPT     udp  --  anywhere             anywhere             udp dpt:domain
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:domain
ACCEPT     udp  --  anywhere             anywhere             udp dpt:bootps
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:bootps

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     all  --  anywhere             192.168.100.0/24     state RELATED,ESTABLISHED
ACCEPT     all  --  192.168.100.0/24     anywhere            
ACCEPT     all  --  anywhere             anywhere            
REJECT     all  --  anywhere             anywhere             reject-with icmp-port-unreachable
REJECT     all  --  anywhere             anywhere             reject-with icmp-port-unreachable
ACCEPT     all  --  anywhere             81.187.2.160/28     
ACCEPT     all  --  81.187.2.160/28      anywhere            
ACCEPT     all  --  anywhere             anywhere            
REJECT     all  --  anywhere             anywhere             reject-with icmp-port-unreachable
REJECT     all  --  anywhere             anywhere             reject-with icmp-port-unreachable
ACCEPT     all  --  anywhere             192.168.122.0/24     state RELATED,ESTABLISHED
ACCEPT     all  --  192.168.122.0/24     anywhere            
ACCEPT     all  --  anywhere             anywhere            
REJECT     all  --  anywhere             anywhere             reject-with icmp-port-unreachable
REJECT     all  --  anywhere             anywhere             reject-with icmp-port-unreachable

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Comment 9 Daniel Berrangé 2012-06-18 13:35:42 UTC
(In reply to comment #7)
> (In reply to comment #3)
> > We presume that the host has a firewall configured with a REJECT policy on
> > the INPUT chain by default (eg the standard Fedora/RHEL iptables config, or
> > an equivalent home-grown setup)
> 
> The assumption is not valid in the general case. The REJECT policy was not
> appropriate here, and was changed. 
> 
> The REJECT policy is just the *default* for Fedora; it's not *mandatory*, so
> we really mustn't ship packages which depend on it.
> 
> A firewall is a band-aid for broken software. In an ideal world, you should
> never need it; the software *itself* should behave correctly (as dnsmasq
> does after my patch). The firewall is an *extra* line of defence.
> 
> If you start to *depend* on the firewall, and use it as an excuse for not
> designing things to be secure in themselves, then the benefit effect is lost.
> 
> You no longer *have* a second line of defence; you're back down to *one*
> line of defence. And now it's not even closely tied to your software — it's
> outside your control and much harder to be sure of.
> 
> We block stuff with a firewall in *addition* to making it secure. Not
> *instead*.

I didn't mean to imply that a firewall should be the only line of defense. I completely agree that dnsmasq should have not allowed this in the first place.

What I meant wrt firewall policy is that when libvirt adds rules to the firewall to open up access to certain traffic, the goal is that libvirt additions should not open the firewall up to unintended traffic. /If/ your firewall had been using a default REJECT policy, then our goals would not have been met, since we mistakenly are allowing DNS queries from the public net which was not our intent when adding the rules, loosing our first layer of defence. Given that your policy was ACCEPT in this case, the libvirt rules weren't allowing anything extra that wasn't already allowed, and clearly dnsmasq should have defended itself in this case.

Comment 10 David Woodhouse 2012-06-18 13:56:45 UTC
Yes, that makes perfect sense then.

Reassigning to dnsmasq....

Comment 11 Simon Kelley 2012-06-18 16:47:26 UTC
Incoming packets are possibly being filtered on two different things here: destination address and arrival interface.

Running dnsmasq with --listen-address=81.187.2.161 means it will respond to packets sent to 81.187.2.161; which interface they arrived on makes no difference.

dnsmasq --bind-interfaces --interface=<vibr> uses just the classic BSD sockets API in the traditional way for a UDP server. --interface=<vibr> is completely equivalent to --listen-address=<address(es) of vibr> It doesn't say anything about the arrival interface of the packet, only the address to which it was sent. Hence the problem in this case when vibr has a routed, public IP address.

Interestingly _without_ --bind-interfaces, --interface _does_ filter on the arrival interface of the packet. Dnsmasq listens on the wildcard address and receives all packets,  it then queries both the destination address and arrival interface, and filters accordingly.  Doing this requires non-portable sockets API extensions, which is partly why --bind-interfaces exists: dnsmasq falls back to that mode when the relevant facilities don't exist on the platform.

David's patch makes dnsmasq with --bind-interfaces work in the same way as dnsmasq without --bind-interfaces, but only on Linux since it uses more non-portable API. There's a nasty choice between the current arrangement where the semantics of --interface varies depending on the presence or absence of --bind-interfaces, and taking David's patch which makes the semantics of --interface independent of --bind-interfaces on Linux, but makes the behaviour of dnsmasq vary over platforms. The incompatible change in behaviour from a decade of previous dnsmasq releases is an issue too.

In any case, it's likely that libvirt will have to use -interface and not --listen-address if it is desired to change the outcome in this situation.

As an aside, the name "bind-interfaces" is perhaps unfortunate. It doesn't do what it sounds like it should do in this context.

Cheers,

Simon.

Comment 12 David Woodhouse 2012-06-18 16:58:42 UTC
Simon, thanks for the analysis.

Please could you confirm my understanding: If we drop the --bind-interfaces option, dnsmasq will correctly drop the inappropriate requests rather than replying to them... but we won't be able to run more than one instance of dnsmasq?

If so, then I don't think we can get away with that change. Should we add a *new* option to actually make it, well, bind to the interfaces? (Rather than their IP addresses as --bind-interfaces does. I'll let you name it. ☺)

Failing that, what would you recommend is the best way to use dnsmasq from libvirt?

Comment 13 Simon Kelley 2012-06-20 19:23:37 UTC
> Please could you confirm my understanding: If we drop the --bind-interfaces
> option, dnsmasq will correctly drop the inappropriate requests rather than
> replying to them... but we won't be able to run more than one instance of
> dnsmasq?

It's slighly worse than that: You won't be able to run _any_ DNS server that wants to bind port 53, not any DHCP server or tftp server, if appropriate.

There's no easy solution that works in every case. A single "daemon" dnsmasq that has a hand-crafted configuration will do everything that's necessary, but that's incompatible with any sort of package automation.

Starting a dnsmasq for each function (network DNS server, local DNS cache, DHCP server for libvirt virtual network.... ) solves the configuration problem but it's very difficult to get many instances to co-exist. Every single instance must set --bind-interfaces, and that has downsides, it stops dnsmasq coping with dynamically created interfaces and (as you've discovered) it has access-control implications.

Ubuntu are currently wrestling with this big-time because they're spawning a dnsmasq from networkmanager to do local resolving but that interferes with any concurrent use of dnsmasq as a DHCP and DNS server on the network. It can be made to work by setting --bind-interfaces on all the instances and listening on disjoint sets of addresses, but the "server" dnsmasq installation might break with --bind-interfaces, especially if it's assuming that dynamically created interfaces will work.

>
> If so, then I don't think we can get away with that change. Should we add a
> *new* option to actually make it, well, bind to the interfaces? (Rather than
> their IP addresses as --bind-interfaces does. I'll let you name it. ☺)

Prompted partly by the Ubuntu impasse and accelerated by this one, I've added a _third_ mode, which is has a desirable mixture of the properties of the current two. Essentially, dnsmasq binds the addresses of individual interfaces rather than the wildcard address, making it less of a bully for other dnsmasq instances or DNS servers, but it would uses netlink to track the creation of new interfaces or the addition  of new addresses to existing interfaces, and automatically bind them as required. This mode is inherently Linux-specific, since it needs netlink to work. The access-control works in the same way at NOT --bind-interfaces (ie it checks the arrival interface of packets) So using --bind-dynamic instead of --bind-interfaces will solve your problem.

Will solve, since this code is in the repo and release 2.63test1 but not yet in any stable release.

Cheers,

Simon.

Comment 14 David Woodhouse 2012-06-20 20:04:30 UTC
Thanks. Any particular reason for doing it that way instead of using SO_BINDTODEVICE? FreeBSD at least has an equivalent of SO_BINDTODEVICE, it seems:
http://lists.freebsd.org/pipermail/freebsd-net/2007-March/013510.html

Comment 15 David Woodhouse 2012-07-08 10:11:31 UTC
Ping? And can we stop this bug from being private please? There's no reason for it to be so, and I can't seem to do it myself.

Comment 16 Jan Lieskovsky 2012-07-09 11:39:48 UTC
Created dnsmasq tracking bugs for this issue

Affects: fedora-all [bug 838528]

Comment 17 Jan Lieskovsky 2012-07-09 12:08:23 UTC
CVE Request:
http://www.openwall.com/lists/oss-security/2012/07/09/1

Comment 18 Douglas Schilling Landgraf 2012-07-09 13:02:00 UTC
Based on comment#13 waiting release 2.63 be launched to provide a new fedora package.

Comment 19 Kurt Seifried 2012-07-12 17:12:28 UTC
Added CVE as per http://www.openwall.com/lists/oss-security/2012/07/12/5

Comment 20 David Woodhouse 2012-07-29 23:22:44 UTC
This security bug is now six weeks old. I've had the ISP reassign a new range of IP addresses to replace the range that was being used for my virtual machines, since the old address is *still* receiving a large number of queries.

I've reinstalled the VM host (for other reasons)... would I be right in thinking that six weeks later, this bug is *still* unfixed in Fedora and I'm going to need to fix it manually?

Is there an ETA for getting a fix into Fedora updates?

Comment 22 David Woodhouse 2012-11-05 22:07:28 UTC
I've had to retire the original IP address range and have the ISP assign me another to use for libvirt. I've updated this machine to F18 and this appears to *still* be broken. Are we not doing security updates any more?

Comment 28 Tomáš Hozza 2012-11-08 10:05:22 UTC
Created attachment 640706 [details]
Commit from upstream git (tag v2.63test1) for reference

Adding upstream commit for reference.

Comment 31 David Woodhouse 2012-11-08 10:14:46 UTC
Thanks. I think this needs a corresponding patch to libvirt to use the new option? If you have that (or can tell me how to fake it), I can test locally.

Comment 32 Tomáš Hozza 2012-11-08 10:40:38 UTC
(In reply to comment #31)
> Thanks. I think this needs a corresponding patch to libvirt to use the new
> option?

Yes, I think libvirt needs to be patched to use the new "--bind-dynamic" option.

> If you have that (or can tell me how to fake it), I can test locally.

Unfortunately I have no experiences with libvirt so I'm not able to prepare the patch for it.

Although it would be good to test if patched dnsmasq works also with current libvirt to test if the patch didn't break anything (I think it shouldn't).  

Here is scratch build for RHEL5:
https://brewweb.devel.redhat.com/taskinfo?taskID=5062119
Here is scratch build for RHEL6:
https://brewweb.devel.redhat.com/taskinfo?taskID=5062147

If you need scratch build for other versions, just let me know.

Comment 33 David Woodhouse 2012-11-08 11:39:16 UTC
For Fedora 18 please. I did have a brief look but the patch didn't apply cleanly and I haven't got round to fixing it up yet so if you have one, that would be appreciated. Thanks.

Comment 34 Tomáš Hozza 2012-11-08 12:18:02 UTC
(In reply to comment #33)
> For Fedora 18 please. I did have a brief look but the patch didn't apply
> cleanly and I haven't got round to fixing it up yet so if you have one, that
> would be appreciated. Thanks.

In fedora 18, there is already version 2.63 which fixes this problem. You can find Fedora 18 build here:
http://koji.fedoraproject.org/koji/buildinfo?buildID=361763

Comment 35 David Woodhouse 2012-11-08 12:56:59 UTC
Ah, but that isn't in updates-testing? Installing it manually, and restarting libvirt's instance of it manually with --bind-dynamic instead of --bind-interfaces, it doesn't seem to fix the problem. It still answers queries received from external interfaces:

/sbin/dnsmasq --strict-order --bind-interfaces --local=// --domain-needed --pid-file=/var/run/libvirt/network/net3.pid --conf-file= --except-interface lo --listen-address 90.155.50.33 --dhcp-range 90.155.50.34,90.155.50.46 --dhcp-leasefile=/var/lib/libvirt/dnsmasq/net3.leases --dhcp-lease-max=13 --dhcp-no-override --dhcp-hostsfile=/var/lib/libvirt/dnsmasq/net3.hostsfile --addn-hosts=/var/lib/libvirt/dnsmasq/net3.addnhosts

I've configured the border router to reject *all* incoming packets for 90.155.50.33 to avoid it being 'discovered' again while it's vulnerable, but I can test from elsewhere on my internal network (just inside the border router, for example), and the Fedora 18 box is still answering queries directed at 90.155.50.33.

Did I do the test wrong? Can you show me how you did your *successful* test when building and testing this update?

Comment 36 David Woodhouse 2012-11-08 13:03:14 UTC
Aha, this works better:
/sbin/dnsmasq --strict-order --bind-dynamic --local=// --domain-needed --pid-file=/var/run/libvirt/network/net3.pid --conf-file= --interface virbr1 --dhcp-range 90.155.50.34,90.155.50.46 --dhcp-leasefile=/var/lib/libvirt/dnsmasq/net3.leases --dhcp-lease-max=13 --dhcp-no-override --dhcp-hostsfile=/var/lib/libvirt/dnsmasq/net3.hostsfile --addn-hosts=/var/lib/libvirt/dnsmasq/net3.addnhosts

That is, I have to use '--interface virbr1' instead of '--except-interface lo --listen-address 90.155.50.33'.

It still accepts requests received from lo, which confused me momentarily, but it *is* correctly dropping requests received from elsewhere. Although it would be better to reject them with UDP port unreachable errors, rather than reject. Dropping packets is always a bad thing.

Comment 37 David Woodhouse 2012-11-08 13:03:51 UTC
Should we open a separate bug, marked F18Blocker, for libvirt to make use of this?

Comment 38 Eric Blake 2012-11-08 17:02:11 UTC
(In reply to comment #37)
> Should we open a separate bug, marked F18Blocker, for libvirt to make use of
> this?

Yes - creating the clone now.

Comment 39 Laine Stump 2012-11-08 18:27:41 UTC
If libvirt changes its usage of dnsmasq to use --bind-dynamic , it *must* be done in a way that libvirt will continue to operate properly (including calling dnsmasq in an appropriate manner) even on systems that don't have a dnsmasq with --bind-dynamic.

So, what must be done is to do a preliminary run of "dnsmasq --help", then parse the output to see if it contains --bind-dynamic, and *only then* change the behavior. Doing otherwise will adversely affect all the libvirt users who don't have a sufficiently modern dnsmasq (the vast majority of which will see no behavioral change from this commandline change anyway - see the next paragraph), and I don't see that as acceptable.


Note that this situation only arises when a network is defined with <forward mode='route'>, and that is arguably the *least* common method of setting up a libvirt network by far (it's much more common to use <forward mode='nat'>)

(Beyond that, in the general sense, I think this is actually how a listener on a publicly visible IP of a multihomed host for a port that has been opened for incoming connections "on all interfaces" is normally expected to operate (and remember that all the addresses in a libvirt network using <forward mode='route' are considered to be public). Granted, this is a slightly different situation, since this second interface is really there for the benefit of the guests, but truthfully once I read through all the comments and fully understood what was happening, my thought was "well of course it's responding." If it was the case that this dnsmasq instance was answering queries sent to the server's *external* IP address, or if queries from the external network to a truly private address (e.g. 192.168.122.1 of libvirt's "default" network which uses forward mode='nat') were responded to, that would be a more serious issue.) I'll happily cede that point though, and agree that we should make libvirt's DNS server instances only answer queries that originate from guests on that network's bridge.

Comment 45 Laine Stump 2012-11-22 02:57:53 UTC
I've posted a series of 3 patches resolving the libvirt part of the bug to libvir-list. After it is pushed, I will backport to the various distros:

  https://www.redhat.com/archives/libvir-list/2012-November/msg00942.html

Please respond to the patch emails with specific comments/suggestions.

Comment 47 Laine Stump 2012-11-29 20:30:55 UTC
Patches for libvirt to support the new dnsmasq --bind-dynamic option have been pushed upstream:

commit 719c2c7665e5826a8cf05531080fe20354b39de1
Author: Laine Stump <laine>
Date:   Tue Nov 20 12:22:15 2012 -0500

    util: capabilities detection for dnsmasq
    
    In order to optionally take advantage of new features in dnsmasq when
    the host's version of dnsmasq supports them, but still be able to run
    on hosts that don't support the new features, we need to be able to
    detect the version of dnsmasq running on the host, and possibly
    determine from the help output what options are in this dnsmasq.
    
    This patch implements a greatly simplified version of the capabilities
    code we already have for qemu. A dnsmasqCaps device can be created and
    populated either from running a program on disk, reading a file with
    the concatenated output of "dnsmasq --version; dnsmasq --help", or
    examining a buffer in memory that contains the concatenated output of
    those two commands. Simple functions to retrieve capabilities flags,
    the version number, and the path of the binary are also included.
    
    bridge_driver.c creates a single dnsmasqCaps object at driver startup,
    and disposes of it at driver shutdown. Any time it must be used, the
    dnsmasqCapsRefresh method is called - it checks the mtime of the
    binary, and re-runs the checks if the binary has changed.
    
    networkxml2argvtest.c creates 2 "artificial" dnsmasqCaps objects at
    startup - one "restricted" (doesn't support --bind-dynamic) and one
    "full" (does support --bind-dynamic). Some of the test cases use one
    and some the other, to make sure both code pathes are tested.

commit bf402e77b6d53a4e569b3aa76aef9c7d589c0cf2
Author: Laine Stump <laine>
Date:   Wed Nov 21 21:17:30 2012 -0500

    util: new virSocketAddrIsPrivate function
    
    This new function returns true if the given address is in the range of
    any "private" or "local" networks as defined in RFC1918 (IPv4) or
    RFC3484/RFC4193 (IPv6), otherwise they return false.
    
    These ranges are:
    
       192.168.0.0/16
       172.16.0.0/16
       10.0.0.0/24
       FC00::/7
       FEC0::/10

commit 753ff83a50263d6975f88d6605d4b5ddfcc97560
Author: Laine Stump <laine>
Date:   Wed Nov 21 21:21:02 2012 -0500

    network: use dnsmasq --bind-dynamic when available
    
    This bug resolves CVE-2012-3411, which is described in the following
    bugzilla report:

Comment 51 Tim Flink 2012-11-30 20:36:47 UTC
The impact of this is "moderate" which is less than "important" and thus this bug does not qualify as a release blocking bug for F18 final. The release criterion in question [1] is:

The release must contain no known security bugs of 'important' or higher impact according to the Red Hat severity classification scale which cannot be satisfactorily resolved by a package update (e.g. issues during installation)

-1 blocker, +1 NTH

Comment 52 Adam Williamson 2012-12-01 08:29:54 UTC
agreed with tflink, -1 blocker, +1 nth.

Comment 53 Jaroslav Reznik 2012-12-04 12:20:44 UTC
Based on final release criterion (as mentioned above),
-1 blocker, +1 nth

Comment 55 Tim Flink 2012-12-04 20:56:44 UTC
I count -3 blocker, +3 NTH. Moving to rejected blocker, accepted NTH. A tested fix would be considered past freeze.

Comment 56 Tomas Hoger 2012-12-14 09:36:31 UTC
This bug is not against Fedora product, and AcceptedNTH in its whiteboard is causing issues elsewhere.  Ok to set that on bug 882309, along with Blocks F18-accepted ?

Comment 57 Laine Stump 2012-12-14 15:22:40 UTC
The confusion is probably due to the fact tha this BZ was originally filed against Fedora (although it was Fedora 17, not 18) and was later co-opted by the security team.

Somebody who knows the Fedora process better will need to comment on whether it's appropriate to set the flags on Buf 882309 instead (I notice that is has release set to Fedora 17, not 18, but don't know if that matters, once the proper flags are set).

Comment 58 Adam Williamson 2012-12-14 21:28:47 UTC
yeah, moving the NTH status there would work. I'm intrigued as to how our little whiteboard field is causing trouble for anything else, but hey.

Comment 59 Yap Sok Ann 2013-02-01 03:58:47 UTC
@Laine Stump, I kinda agree with the point ceded in comment 39. Is there anyway to revert to the old behavior, i.e. allowing dnsmasq to be queried from outside? AT the moment, there doesn't seem to be any relevant setting in http://libvirt.org/formatnetwork.html

Comment 60 Laine Stump 2013-02-05 04:26:04 UTC
(In reply to comment #59)
> @Laine Stump, I kinda agree with the point ceded in comment 39. Is there
> anyway to revert to the old behavior, i.e. allowing dnsmasq to be queried
> from outside? AT the moment, there doesn't seem to be any relevant setting
> in http://libvirt.org/formatnetwork.html

No, there is currently no way to revert to the old behavior, although dnsmasq has just added back support for querying libvirt's dnsmasq instances directly from the host. See Bug 904940.

Comment 61 errata-xmlrpc 2013-02-21 10:44:44 UTC
This issue has been addressed in following products:

  Red Hat Enterprise Linux 6

Via RHSA-2013:0277 https://rhn.redhat.com/errata/RHSA-2013-0277.html

Comment 63 errata-xmlrpc 2013-02-28 18:57:54 UTC
This issue has been addressed in following products:

  RHEV-H and Agents for RHEL-6

Via RHSA-2013:0579 https://rhn.redhat.com/errata/RHSA-2013-0579.html

Comment 64 Paul Wouters 2013-04-14 04:39:38 UTC
I was hit by this now too. Worse, my dnsmasq was a participant in a DDOS attack being queried with fake source IPs doing ANY queries for isc.org, a well known amplifying query.

0:24:33.991446 IP 95.211.225.167.25345 > 76.10.157.69.domain: 10809+ [1au] ANY? isc.org. (36)
00:24:33.992160 IP 76.10.157.69.domain > 95.211.225.167.25345: 10809 27/0/9 SOA, RRSIG, NS ams.sns-pb.isc.org., NS sfba.sns-pb.isc.org., NS ord.sns-pb.isc.org., NS ns.isc.afilias-nst.info., RRSIG, A 149.20.64.42, RRSIG, MX mx.ams1.isc.org. 10, MX mx.pao1.isc.org. 10, RRSIG, TXT "v=spf1 a mx ip4:204.152.184.0/21 ip4:149.20.0.0/16 ip6:2001:04F8::0/32 ip6:2001:500:60::65/128 ~all", TXT "$Id: isc.org,v 1.1792 2013-04-02 00:33:44 bind Exp $", RRSIG, AAAA 2001:4f8:0:2::d, RRSIG[|domain]
00:24:34.513888 IP 23.29.113.102.25448 > 76.10.157.69.domain: 7490+ [1au] ANY? isc.org. (36)
00:24:34.514594 IP 76.10.157.69.domain > 23.29.113.102.25448: 7490 27/0/9 SOA, RRSIG, NS ams.sns-pb.isc.org., NS sfba.sns-pb.isc.org., NS ord.sns-pb.isc.org., NS ns.isc.afilias-nst.info., RRSIG, A 149.20.64.42, RRSIG, MX mx.ams1.isc.org. 10, MX mx.pao1.isc.org. 10, RRSIG, TXT "v=spf1 a mx ip4:204.152.184.0/21 ip4:149.20.0.0/16 ip6:2001:04F8::0/32 ip6:2001:500:60::65/128 ~all", TXT "$Id: isc.org,v 1.1792 2013-04-02 00:33:44 bind Exp $", RRSIG, AAAA 2001:4f8:0:2::d, RRSIG[|domain]
00:24:34.664537 IP 95.211.225.167.25345 > 76.10.157.69.domain: 10809+ [1au] ANY? isc.org. (36)
00:24:34.665220 IP 76.10.157.69.domain > 95.211.225.167.25345: 10809 27/0/9 SOA, RRSIG, NS ams.sns-pb.isc.org., NS sfba.sns-pb.isc.org., NS ord.sns-pb.isc.org., NS ns.isc.afilias-nst.info., RRSIG, A 149.20.64.42, RRSIG, MX mx.ams1.isc.org. 10, MX mx.pao1.isc.org. 10, RRSIG, TXT "v=spf1 a mx ip4:204.152.184.0/21 ip4:149.20.0.0/16 ip6:2001:04F8::0/32 ip6:2001:500:60::65/128 ~all", TXT "$Id: isc.org,v 1.1792 2013-04-02 00:33:44 bind Exp $", RRSIG, AAAA 2001:4f8:0:2::d, RRSIG[|domain]





This is using Fedora 18 with libvirt-0.10.2.4-1.fc18.x86_64

I'm changing this but to urgent

Comment 65 Cole Robinson 2013-04-14 15:33:25 UTC
Hmm I thought this was supposed to be fixed in F18. Laine, thoughts on Paul's comment?

Comment 66 Laine Stump 2013-04-14 23:00:09 UTC
Well, my first comment is that this BZ is the distro-agnostic CVE BZ; the appropriate BZ for Fedora-specific issues is Bug 838528. I have some questions for Paul which I will post in that BZ. (BTW, as far as I know, only people on the security team are supposed to change the priority of BZs with a product of "Security Response".)

Now for my question wrt this BZ: I'm not sure why this BZ still shows as new - both the Fedora and the RHEL versions of the BZ are marked as CLOSED/ERRATA. Shouldn't this be automatically closed when all the platform-specific bugs are closed?

Comment 67 Tomáš Hozza 2013-04-15 07:21:00 UTC
(In reply to comment #65)
> Hmm I thought this was supposed to be fixed in F18. Laine, thoughts on
> Paul's comment?

It was dnsmasq issue and it has been already fixed in dnsmasq-2.65-2.

Comment 68 Jan Lieskovsky 2013-04-25 09:08:22 UTC
(In reply to comment #66)
> Well, my first comment is that this BZ is the distro-agnostic CVE BZ; the
> appropriate BZ for Fedora-specific issues is Bug 838528. I have some
> questions for Paul which I will post in that BZ. (BTW, as far as I know,
> only people on the security team are supposed to change the priority of BZs
> with a product of "Security Response".)

That is correct. Only Red Hat Security Response Team members are supposed to change the status of Security Response bugs.

> 
> Now for my question wrt this BZ: I'm not sure why this BZ still shows as new
> - both the Fedora and the RHEL versions of the BZ are marked as
> CLOSED/ERRATA. Shouldn't this be automatically closed when all the
> platform-specific bugs are closed?

While the issue has been corrected in Red Hat Enterprise Linux 6 and Fedora products, it still is present in Red Hat Enterprise Linux 5:
  https://bugzilla.redhat.com/show_bug.cgi?id=833033#c62

That's the reason this bug is still in NEW state (will be closed only in moment issue has been resolved in all affected products). {Security Response product bugs have just two states: 1) NEW 2) CLOSED [ERRATA, NOTABUG] etc. - there isn't a way how to specify / note the issue has been already corrected in subset of affected versions}

Hope the above clarifies, Jan.

Comment 69 Vincent Danen 2015-02-26 22:57:49 UTC
Statement:

Red Hat Enterprise Linux 5 is now in Production 3 Phase of the support and maintenance life cycle. This has been rated as having Low security impact and is not currently planned to be addressed in future updates. For additional information, refer to the Red Hat Enterprise Linux Life Cycle: https://access.redhat.com/support/policy/updates/errata/.


Note You need to log in before you can comment on or make changes to this bug.