From: "Daniel P. Berrange" <berrange@redhat.com>
To: qemu-devel@nongnu.org
Cc: "Gerd Hoffmann" <kraxel@redhat.com>,
"Paolo Bonzini" <pbonzini@redhat.com>,
"Philippe Mathieu-Daudé" <f4bug@amsat.org>,
"Eric Blake" <eblake@redhat.com>,
"Daniel P. Berrange" <berrange@redhat.com>
Subject: [Qemu-devel] [PATCH v3 3/5] sockets: ensure we don't accept IPv4 clients when IPv4 is disabled
Date: Thu, 1 Jun 2017 09:29:33 +0100 [thread overview]
Message-ID: <20170601082935.19993-4-berrange@redhat.com> (raw)
In-Reply-To: <20170601082935.19993-1-berrange@redhat.com>
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
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
---
util/qemu-sockets.c | 40 +++++++++++++++++++++++++++++++---------
1 file changed, 31 insertions(+), 9 deletions(-)
diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c
index 81bc8de..852773d 100644
--- a/util/qemu-sockets.c
+++ b/util/qemu-sockets.c
@@ -104,17 +104,16 @@ NetworkAddressFamily inet_netfamily(int family)
* f t PF_INET6
* t - PF_INET
* t f PF_INET
- * t t PF_INET6
+ * t t PF_INET6/PF_UNSPEC
*
* NB, this matrix is only about getting the necessary results
* from getaddrinfo(). Some of the cases require further work
* after reading results from getaddrinfo in order to fully
- * apply the logic the end user wants. eg with the last case
- * ipv4=t + ipv6=t + PF_INET6, getaddrinfo alone can only
- * guarantee the ipv6=t part of the request - we need more
- * checks to provide ipv4=t part of the guarantee. This is
- * outside scope of this method and not currently handled by
- * callers at all.
+ * apply the logic the end user wants.
+ *
+ * In the first and last cases, we must set IPV6_V6ONLY=0
+ * when binding, to allow a single listener to potentially
+ * accept both IPv4+6 addresses.
*/
int inet_ai_family_from_address(InetSocketAddress *addr,
Error **errp)
@@ -124,6 +123,23 @@ int inet_ai_family_from_address(InetSocketAddress *addr,
error_setg(errp, "Cannot disable IPv4 and IPv6 at same time");
return PF_UNSPEC;
}
+ if ((addr->has_ipv6 && addr->ipv6) && (addr->has_ipv4 && addr->ipv4)) {
+ /*
+ * Some backends can only do a single listener. In that case
+ * we want empty hostname to resolve to "::" and then use the
+ * flag IPV6_V6ONLY==0 to get both protocols on 1 socket. This
+ * doesn't work for addresses other than "", so they're just
+ * inevitably broken until multiple listeners can be used,
+ * and thus we honour getaddrinfo automatic protocol detection
+ * Once all backends do multi-listener, remove the PF_INET6
+ * branch entirely.
+ */
+ if (!addr->host || g_str_equal(addr->host, "")) {
+ return PF_INET6;
+ } else {
+ return PF_UNSPEC;
+ }
+ }
if ((addr->has_ipv6 && addr->ipv6) || (addr->has_ipv4 && !addr->ipv4)) {
return PF_INET6;
}
@@ -213,8 +229,14 @@ static int inet_listen_saddr(InetSocketAddress *saddr,
port_max = saddr->has_to ? saddr->to + port_offset : port_min;
for (p = port_min; p <= port_max; p++) {
#ifdef IPV6_V6ONLY
- /* listen on both ipv4 and ipv6 */
- int v6only = 0;
+ /*
+ * Deals with first & last cases in matrix in comment
+ * for inet_ai_family_from_address().
+ */
+ int v6only =
+ ((!saddr->has_ipv4 && !saddr->has_ipv6) ||
+ (saddr->has_ipv4 && saddr->ipv4 &&
+ saddr->has_ipv6 && saddr->ipv6)) ? 0 : 1;
#endif
inet_setport(e, p);
#ifdef IPV6_V6ONLY
--
2.9.3
next prev parent reply other threads:[~2017-06-01 8:29 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-06-01 8:29 [Qemu-devel] [PATCH v3 0/5] Fix handling of IPv4/IPv6 dual stack Daniel P. Berrange
2017-06-01 8:29 ` [Qemu-devel] [PATCH v3 1/5] sockets: ensure we can bind to both ipv4 & ipv6 separately Daniel P. Berrange
2017-06-01 8:29 ` [Qemu-devel] [PATCH v3 2/5] sockets: don't block IPv4 clients when listening on "::" Daniel P. Berrange
2017-06-01 8:29 ` Daniel P. Berrange [this message]
2017-06-02 4:45 ` [Qemu-devel] [PATCH v3 3/5] sockets: ensure we don't accept IPv4 clients when IPv4 is disabled Philippe Mathieu-Daudé
2017-06-01 8:29 ` [Qemu-devel] [PATCH v3 4/5] io: preserve ipv4/ipv6 flags when resolving InetSocketAddress Daniel P. Berrange
2017-06-01 8:29 ` [Qemu-devel] [PATCH v3 5/5] tests: add functional test validating ipv4/ipv6 address flag handling Daniel P. Berrange
2017-06-06 10:32 ` [Qemu-devel] [PATCH v3 0/5] Fix handling of IPv4/IPv6 dual stack Gerd Hoffmann
2017-06-10 16:06 ` Vlad Yasevich
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170601082935.19993-4-berrange@redhat.com \
--to=berrange@redhat.com \
--cc=eblake@redhat.com \
--cc=f4bug@amsat.org \
--cc=kraxel@redhat.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.