Bug 886821

Summary: libvirt-launched dnsmasq listens on localhost when it shouldn't
Product: Red Hat Enterprise Linux 6 Reporter: Laine Stump <laine>
Component: libvirtAssignee: Laine Stump <laine>
Status: CLOSED ERRATA QA Contact: Virtualization Bugs <virt-bugs>
Severity: medium Docs Contact:
Priority: medium    
Version: 6.3CC: acathrow, dallan, dyasny, dyuan, jlayton, mjenner, mzhan, rwu, tlavigne, whuang, ydu
Target Milestone: rc   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: libvirt-0.10.2-13.el6 Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: 886663 Environment:
Last Closed: 2013-02-21 07:28:31 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 895654    

Description Laine Stump 2012-12-13 09:13:32 UTC
+++ This bug was initially created as a clone of Bug #886663 +++

I'm running libvirt-0.10.2.2-1.fc18.x86_64. I have my VPN config into work set up to run a dnsmasq on the loopback for split DNS. After the latest libvirt update however, I found that it failed to start because something was listening on the port. That something is the dnsmasq that libvirt fires up to handle virbr0:

[root@tlielax ~]# ps -ef | grep dnsmasq
nobody   12148     1  0 15:08 ?        00:00:00 /sbin/dnsmasq --strict-order --local=// --domain-needed --pid-file=/var/run/libvirt/network/default.pid --conf-file= --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 --dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile --addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts
root     12243 10766  0 15:09 pts/0    00:00:00 grep --color=auto dnsmasq
[root@tlielax ~]# lsof -p 12148 -n -P
lsof: WARNING: can't stat() fuse.gvfsd-fuse file system /run/user/4447/gvfs
      Output information may be incomplete.
COMMAND   PID   USER   FD      TYPE             DEVICE SIZE/OFF      NODE NAME
dnsmasq 12148 nobody  cwd       DIR              253,2     4096       128 /
dnsmasq 12148 nobody  rtd       DIR              253,2     4096       128 /
dnsmasq 12148 nobody  txt       REG              253,2   257584 206781719 /usr/sbin/dnsmasq
dnsmasq 12148 nobody  mem       REG              253,2   294560 136557603 /usr/lib64/libdbus-1.so.3.7.2
dnsmasq 12148 nobody  mem       REG              253,2    62416 137139879 /usr/lib64/libnss_files-2.16.so
dnsmasq 12148 nobody  mem       REG              253,2    44272 137139891 /usr/lib64/librt-2.16.so
dnsmasq 12148 nobody  mem       REG              253,2   141296 137139887 /usr/lib64/libpthread-2.16.so
dnsmasq 12148 nobody  mem       REG              253,2  2067976 136017844 /usr/lib64/libc-2.16.so
dnsmasq 12148 nobody  mem       REG              253,2   160344 136421458 /usr/lib64/ld-2.16.so
dnsmasq 12148 nobody    0u      CHR                1,3      0t0      1028 /dev/null
dnsmasq 12148 nobody    1u      CHR                1,3      0t0      1028 /dev/null
dnsmasq 12148 nobody    2u      CHR                1,3      0t0      1028 /dev/null
dnsmasq 12148 nobody    3u      REG              253,2        0  10904807 /var/lib/libvirt/dnsmasq/default.leases
dnsmasq 12148 nobody    4u     IPv4             272885      0t0       UDP *:67 
dnsmasq 12148 nobody    5u  netlink                         0t0    272886 ROUTE
dnsmasq 12148 nobody    6u     IPv4             272894      0t0       UDP 192.168.122.1:53 
dnsmasq 12148 nobody    7u     IPv4             272895      0t0       TCP 192.168.122.1:53 (LISTEN)
dnsmasq 12148 nobody    8u     IPv4             272896      0t0       UDP 127.0.0.1:53 
dnsmasq 12148 nobody    9u     IPv4             272897      0t0       TCP 127.0.0.1:53 (LISTEN)
dnsmasq 12148 nobody   10u     IPv6             272898      0t0       UDP [::1]:53 
dnsmasq 12148 nobody   11u     IPv6             272899      0t0       TCP [::1]:53 (LISTEN)
dnsmasq 12148 nobody   12r     FIFO                0,8      0t0    272904 pipe
dnsmasq 12148 nobody   13w     FIFO                0,8      0t0    272904 pipe
dnsmasq 12148 nobody   14u     unix 0xffff8803e74b2700      0t0    273464 socket

The dnsmasq launched by libvirt used to just listen on 192.168.122.1, but now it listens on the loopback too. That prevents my other dnsmasq server from starting and doesn't seem correct.

My suspicion would be this change in the changelog:

- CVE-2012-3411: avoid open DNS proxy with dnsmasq (bz #874702, bz #882309)

...but I'll leave the diagnosis to others to determine. Perhaps you still need the "--except-interface lo" in the command line as well?

--- Additional comment from Jeff Layton on 2012-12-12 15:17:59 EST ---

Note too that if I start the libvirt virtual network after starting my other dnsmasq server that it doesn't end up listening on localhost.

--- Additional comment from Cole Robinson on 2012-12-12 15:41:00 EST ---

Huh, I was hitting this too but didn't realize it was libvirt related.

I verified that adding '--except-interface lo' to the new 0.10.2.2 dnsmasq command line generates similar lsof output to 0.10.2.1 dnsmasq command line (basically what Jeff reported above, but without the 127.0.0.1 and [::1] bits)

The easiest way to have network manager run dnsmasq is adding 'dns=dnsmasq' to /etc/NetworkManager/NetworkManager.conf and logout/login

Laine, thoughts?

--- Additional comment from Jeff Layton on 2012-12-12 16:00:29 EST ---

Yeah, in fact:

       -i, --interface=<interface name>
              Listen only on the specified interface(s). Dnsmasq automatically
              adds the loopback (local) interface to the list of interfaces to
              use  when  the --interface option  is used. If no --interface or
              --listen-address options are given dnsmasq listens on all avail‐
              able  interfaces except any given in --except-interface options.
              IP alias interfaces (eg "eth1:0") cannot be used  with  --inter‐
              face   or   --except-interface   options,  use  --listen-address
              instead.

...so if you don't include --except-interface=lo then it will the loopback automatically. Seems like a mis-feature to me, but whatever... ;)

--- Additional comment from Laine Stump on 2012-12-12 21:35:23 EST ---

My recollection is that when I tried only switching --listen-address= to --interface=, the problem described in CVE 2012-3411 (Bug 833033) remained, but went away when I also removed --except-interface=lo. Something else could have been happening, so I'll double check tonight.

--- Additional comment from Laine Stump on 2012-12-13 01:00:27 EST ---

Bah.

I apparently was lacking sleep when I tested, and gave too much credence to the suggestion in https://bugzilla.redhat.com/show_bug.cgi?id=833033#c36 . The bit that didn't get rid of the problem described in the CVE was adding --interface without removing --listen-address; leaving in --except-interface has no ill effects wrt. the CVE.

I'm creating patches now for all the affected branches.

Sorry for the inconvenience :-(

--- Additional comment from Laine Stump on 2012-12-13 02:14:47 EST ---

BTW, I've just discovered that if the non-libvirt dnsmasq instance uses "bind-dynamic" instead of "bind-interfaces", it will be able to start; likewise if the non-libvirt dnsmasq is already running when libvirt starts its networks (even with "bind-interfaces" instead of "bind-dynamic" (I didn't check which dnsmasq actually receives the DNS requests sent to 127.0.0.1, since the answer will anyway be "the *wrong* one" in at least one of those cases)

--- Additional comment from Laine Stump on 2012-12-13 04:10:41 EST ---

Fix posted upstream. Waiting for ACK:

https://www.redhat.com/archives/libvir-list/2012-December/msg00767.html

I did test that it both fixed this new problem, and didn't un-fix the CVE. I also posted a backport to the v0.10.2-maint branch, since the code being fixed is all changed since then, so a cherry-pick wouldn't suffice.

I don't know if it's any longer possible to get anything into F18, so this may have to be a 0-day update.

Comment 3 yanbing du 2012-12-20 06:11:35 UTC
Test with:
libvirt-0.10.2-13.el6.x86_64
dnsmasq-2.48-12.el6.x86_64

#  ps -ef |grep dnsmasq
nobody    8382     1  0 11:04 ?        00:00:00 /usr/sbin/dnsmasq --strict-order --local=// --domain-needed --pid-file=/var/run/libvirt/network/default.pid --conf-file= --except-interface lo --bind-interfaces --listen-address 192.168.122.1 --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 --dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile --addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts

# lsof -p 8382 -n -P
COMMAND  PID   USER   FD   TYPE             DEVICE SIZE/OFF    NODE NAME
dnsmasq 8382 nobody  cwd    DIR                8,1     4096       2 /
dnsmasq 8382 nobody  rtd    DIR                8,1     4096       2 /
dnsmasq 8382 nobody  txt    REG                8,1   180176  667765 /usr/sbin/dnsmasq
dnsmasq 8382 nobody  mem    REG                8,1   156872  931139 /lib64/ld-2.12.so
dnsmasq 8382 nobody  mem    REG                8,1  1922152  931141 /lib64/libc-2.12.so
dnsmasq 8382 nobody  mem    REG                8,1   145720  931147 /lib64/libpthread-2.12.so
dnsmasq 8382 nobody  mem    REG                8,1    47064  920631 /lib64/librt-2.12.so
dnsmasq 8382 nobody  mem    REG                8,1   268232  931159 /lib64/libdbus-1.so.3.4.0
dnsmasq 8382 nobody  mem    REG                8,1    65928  920434 /lib64/libnss_files-2.12.so
dnsmasq 8382 nobody    0u   CHR                1,3      0t0    3698 /dev/null
dnsmasq 8382 nobody    1u   CHR                1,3      0t0    3698 /dev/null
dnsmasq 8382 nobody    2u   CHR                1,3      0t0    3698 /dev/null
dnsmasq 8382 nobody    3u  sock                0,6      0t0  134665 can't identify protocol
dnsmasq 8382 nobody    4u   REG                8,1        0 1187408 /var/lib/libvirt/dnsmasq/default.leases
dnsmasq 8382 nobody    5u  IPv4             134666      0t0     UDP *:67 
dnsmasq 8382 nobody    6u  IPv4             134675      0t0     TCP 192.168.122.1:53 (LISTEN)
dnsmasq 8382 nobody    7u  IPv4             134676      0t0     UDP 192.168.122.1:53 
dnsmasq 8382 nobody    8r  FIFO                0,8      0t0  134681 pipe
dnsmasq 8382 nobody    9w  FIFO                0,8      0t0  134681 pipe
dnsmasq 8382 nobody   10u  unix 0xffff8801203aa0c0      0t0  134683 socket

libvirt add "--except-interface lo" option when start the dnsmasq process, and it does not listen "127.0.0.1:53" and  "[::1]:53 ".
So this bug is VERIFIED.

Comment 4 errata-xmlrpc 2013-02-21 07:28:31 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory, and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

http://rhn.redhat.com/errata/RHSA-2013-0276.html