Red Hat Bugzilla – Bug 1454367
QEMU fails to reject IPv4 connections when IPv4 listening is disabled
Last modified: 2018-04-10 20:25:34 EDT
Description of problem: The QEMU network backends (VNC, migration, chardev) accept flags "ipv6=on|off" and "ipv4=on|off" as a way to control which protocols they listen for connections. When setting either ipv4=off, ipv6=on, or ipv6, QEMU should not accept connections from IPv4 clients. This is not, however, the case currently - the following combinations: $QEMU -incoming tcp::9000,ipv6=on $QEMU -incoming tcp:[::]:9000,ipv6=on $QEMU -chardev socket,id=cdev0,host=,port=9000,server,nowait,ipv4=off $QEMU -chardev socket,id=cdev0,host=,port=9000,server,nowait,ipv6=on $QEMU -chardev socket,id=cdev0,host=::,port=9000,server,nowait,ipv4=off $QEMU -chardev socket,id=cdev0,host=::,port=9000,server,nowait,ipv6=on $QEMU -vnc :0,ipv4=off $QEMU -vnc :0,ipv6=on $QEMU -vnc :::0,ipv4=off $QEMU -vnc :::0,ipv6=on all allow an IPv4 client to connect, despite being told to accept IPv6 only. This is due to a bug in QEMU whereby it sets IPV6_V6ONLY=0, instead of =1, thereby allowing IPv4 clients over the IPv6 socket. Version-Release number of selected component (if applicable): qemu-kvm-rhev-2.9.0-1.el7 How reproducible: Always Steps to Reproduce: 1. $QEMU -incoming tcp::9000,ipv6=on 2. telnet 127.0.0.1 9000 3. (Repeat for all the examples shown earlier) Actual results: Client succesfully connects to 127.0.0.1, port 9000 Expected results: Client fails to connect to 127.0.0.1 with "COnnection refused" message. Additional info:
The scenarios describe are fixed by patches 3 & 4 in this small series https://lists.gnu.org/archive/html/qemu-devel/2017-05/msg04707.html
Will be picked up for 7.5 via rebase, because it is included in upstream 2.10: commit 563a3987b980a36e6941720a99d5cf36960f78ea Author: Daniel P. Berrange <berrange@redhat.com> Date: Wed May 17 14:34:36 2017 +0100 io: preserve ipv4/ipv6 flags when resolving InetSocketAddress The original InetSocketAddress struct may have has_ipv4 and has_ipv6 fields set, which will control both the ai_family used during DNS resolution, and later use of the V6ONLY flag. Currently the standalone DNS resolver code drops the has_ipv4 & has_ipv6 flags after resolving, which means the later bind() code won't correctly set V6ONLY. This fixes the following scenarios -vnc :0,ipv4=off -vnc :0,ipv6=on -vnc :::0,ipv4=off -vnc :::0,ipv6=on which all mistakenly accepted IPv4 clients Acked-by: Gerd Hoffmann <kraxel@gmail.com> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Reviewed-by: Eric Blake <eblake@redhat.com> Signed-off-by: Daniel P. Berrange <berrange@redhat.com> commit 94bc0d19789b6f5ce881c4a06a3e1c431874cbbd Author: Daniel P. Berrange <berrange@redhat.com> Date: Wed May 17 14:17:55 2017 +0100 sockets: ensure we don't accept IPv4 clients when IPv4 is disabled Currently if you disable listening on IPv4 addresses, via the CLI flag ipv4=off, we still mistakenly accept IPv4 clients via the IPv6 listener socket due to IPV6_V6ONLY flag being unset. We must ensure IPV6_V6ONLY is always set if ipv4=off This fixes the following scenarios -incoming tcp::9000,ipv6=on -incoming tcp:[::]:9000,ipv6=on -chardev socket,id=cdev0,host=,port=9000,server,nowait,ipv4=off -chardev socket,id=cdev0,host=,port=9000,server,nowait,ipv6=on -chardev socket,id=cdev0,host=::,port=9000,server,nowait,ipv4=off -chardev socket,id=cdev0,host=::,port=9000,server,nowait,ipv6=on which all mistakenly accepted IPv4 clients Acked-by: Gerd Hoffmann <kraxel@gmail.com> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Reviewed-by: Eric Blake <eblake@redhat.com> Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Reproduce host version: qemu-kvm-rhev-2.9.0-1.el7.x86_64 kernel-3.10.0-737.el7.x86_64 test scenarios: # /usr/libexec/qemu-kvm -monitor stdio -vnc :0,ipv4=off # /usr/libexec/qemu-kvm -monitor stdio -vnc :::0,ipv4=off # /usr/libexec/qemu-kvm -monitor stdio -vnc :0,ipv6=on # /usr/libexec/qemu-kvm -monitor stdio -vnc :::0,ipv6=on # /usr/libexec/qemu-kvm -monitor stdio -incoming tcp::9000,ipv6=on # /usr/libexec/qemu-kvm -monitor stdio -incoming tcp:[::]:9000,ipv6=on # /usr/libexec/qemu-kvm -monitor stdio -chardev socket,id=cdev0,host=,port=9000,server,nowait,ipv4=off # /usr/libexec/qemu-kvm -monitor stdio -chardev socket,id=cdev0,host=,port=9000,server,nowait,ipv6=on # /usr/libexec/qemu-kvm -monitor stdio -chardev socket,id=cdev0,host=::,port=9000,server,nowait,ipv4=off # /usr/libexec/qemu-kvm -monitor stdio -chardev socket,id=cdev0,host=::,port=9000,server,nowait,ipv6=on test steps: 1.usr/libexec/qemu-kvm -monitor stdio -incoming tcp::9000,ipv6=on 2.telnet 127.0.0.1 9000 (Repeat for test scenarios shown earlier) Actual results: Client succesfully connects to 127.0.0.1, port 9000 # telnet 127.0.0.1 9000 Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is '^]' ---------------------------- Verify this bug on qemu-kvm-rhev-2.10.0-2.el7.x86_64 as same steps above. Actual results: Client fails to connect to 127.0.0.1 with "Connection refused" message. # telnet 127.0.0.1 9000 Trying 127.0.0.1... telnet: connect to address 127.0.0.1: Connection refused According to result above,this bug has been fixed.
According to comment 10, change to verified status
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. https://access.redhat.com/errata/RHSA-2018:1104