diff mbox

[v2,2/5] sockets: don't block IPv4 clients when listening on "::"

Message ID 20170519180342.19618-3-berrange@redhat.com
State New
Headers show

Commit Message

Daniel P. Berrangé May 19, 2017, 6:03 p.m. UTC
When inet_parse() parses the hostname, it is forcing the
has_ipv6 && ipv6 flags if the address contains a ":". This
means that if the user had set the ipv4=on flag, to try to
restrict the listener to just ipv4, an error would not have
been raised.  eg

   -incoming tcp:[::]:9000,ipv4

should have raised an error because listening for IPv4
on "::" is a non-sensical combination. With this removed,
we now call getaddrinfo() on "::" passing PF_INET and
so getaddrinfo reports an error about the hostname being
incompatible with the requested protocol.

Likewise it is explicitly setting the has_ipv4 & ipv4
flags when the address contains only digits + '.'. This
has no ill-effect, but also has no benefit, so is removed.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
---
 util/qemu-sockets.c | 4 ----
 1 file changed, 4 deletions(-)

Comments

Philippe Mathieu-Daudé May 19, 2017, 11:49 p.m. UTC | #1
On 05/19/2017 03:03 PM, Daniel P. Berrange wrote:
> When inet_parse() parses the hostname, it is forcing the
> has_ipv6 && ipv6 flags if the address contains a ":". This
> means that if the user had set the ipv4=on flag, to try to
> restrict the listener to just ipv4, an error would not have
> been raised.  eg
>
>    -incoming tcp:[::]:9000,ipv4
>
> should have raised an error because listening for IPv4
> on "::" is a non-sensical combination. With this removed,
> we now call getaddrinfo() on "::" passing PF_INET and
> so getaddrinfo reports an error about the hostname being
> incompatible with the requested protocol.
>
> Likewise it is explicitly setting the has_ipv4 & ipv4
> flags when the address contains only digits + '.'. This
> has no ill-effect, but also has no benefit, so is removed.
>
> Signed-off-by: Daniel P. Berrange <berrange@redhat.com>

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

> ---
>  util/qemu-sockets.c | 4 ----
>  1 file changed, 4 deletions(-)
>
> diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c
> index 397212b..b82412e 100644
> --- a/util/qemu-sockets.c
> +++ b/util/qemu-sockets.c
> @@ -618,16 +618,12 @@ int inet_parse(InetSocketAddress *addr, const char *str, Error **errp)
>              error_setg(errp, "error parsing IPv6 address '%s'", str);
>              return -1;
>          }
> -        addr->ipv6 = addr->has_ipv6 = true;
>      } else {
>          /* hostname or IPv4 addr */
>          if (sscanf(str, "%64[^:]:%32[^,]%n", host, port, &pos) != 2) {
>              error_setg(errp, "error parsing address '%s'", str);
>              return -1;
>          }
> -        if (host[strspn(host, "0123456789.")] == '\0') {
> -            addr->ipv4 = addr->has_ipv4 = true;
> -        }
>      }
>
>      addr->host = g_strdup(host);
>
Eric Blake May 22, 2017, 3:30 p.m. UTC | #2
On 05/19/2017 01:03 PM, Daniel P. Berrange wrote:
> When inet_parse() parses the hostname, it is forcing the
> has_ipv6 && ipv6 flags if the address contains a ":". This
> means that if the user had set the ipv4=on flag, to try to
> restrict the listener to just ipv4, an error would not have
> been raised.  eg
> 
>    -incoming tcp:[::]:9000,ipv4
> 
> should have raised an error because listening for IPv4
> on "::" is a non-sensical combination.

If I understand correctly, the correct response (and post-patch
behavior) is an error (mismatch between requesting IPv4-only usage while
giving an IPv6 address), but the buggy response (pre-patch behavior) is
that we ended up setting ipv6 in addition to the user-set ipv4 (because
we found a ':'), and then end up listening on IPv6 after all contrary to
the user's request.


> With this removed,
> we now call getaddrinfo() on "::" passing PF_INET and
> so getaddrinfo reports an error about the hostname being
> incompatible with the requested protocol.
> 
> Likewise it is explicitly setting the has_ipv4 & ipv4
> flags when the address contains only digits + '.'. This
> has no ill-effect, but also has no benefit, so is removed.
> 
> Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
> ---
>  util/qemu-sockets.c | 4 ----
>  1 file changed, 4 deletions(-)

Reviewed-by: Eric Blake <eblake@redhat.com>
Daniel P. Berrangé May 22, 2017, 3:34 p.m. UTC | #3
On Mon, May 22, 2017 at 10:30:55AM -0500, Eric Blake wrote:
> On 05/19/2017 01:03 PM, Daniel P. Berrange wrote:
> > When inet_parse() parses the hostname, it is forcing the
> > has_ipv6 && ipv6 flags if the address contains a ":". This
> > means that if the user had set the ipv4=on flag, to try to
> > restrict the listener to just ipv4, an error would not have
> > been raised.  eg
> > 
> >    -incoming tcp:[::]:9000,ipv4
> > 
> > should have raised an error because listening for IPv4
> > on "::" is a non-sensical combination.
> 
> If I understand correctly, the correct response (and post-patch
> behavior) is an error (mismatch between requesting IPv4-only usage while
> giving an IPv6 address), but the buggy response (pre-patch behavior) is
> that we ended up setting ipv6 in addition to the user-set ipv4 (because
> we found a ':'), and then end up listening on IPv6 after all contrary to
> the user's request.

Yes, with this patch you get this error:

  qemu-system-x86_64: -incoming tcp:[::]:9000,ipv4: address resolution
    failed for :::9000: Address family for hostname not supported

because it now (correctly) tries to resolve "::" as an IPv4 address
and fails (just like -chardev and -vnc already do)

> 
> 
> > With this removed,
> > we now call getaddrinfo() on "::" passing PF_INET and
> > so getaddrinfo reports an error about the hostname being
> > incompatible with the requested protocol.
> > 
> > Likewise it is explicitly setting the has_ipv4 & ipv4
> > flags when the address contains only digits + '.'. This
> > has no ill-effect, but also has no benefit, so is removed.
> > 
> > Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
> > ---
> >  util/qemu-sockets.c | 4 ----
> >  1 file changed, 4 deletions(-)
> 
> Reviewed-by: Eric Blake <eblake@redhat.com>
> 
> -- 
> Eric Blake, Principal Software Engineer
> Red Hat, Inc.           +1-919-301-3266
> Virtualization:  qemu.org | libvirt.org
> 




Regards,
Daniel
diff mbox

Patch

diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c
index 397212b..b82412e 100644
--- a/util/qemu-sockets.c
+++ b/util/qemu-sockets.c
@@ -618,16 +618,12 @@  int inet_parse(InetSocketAddress *addr, const char *str, Error **errp)
             error_setg(errp, "error parsing IPv6 address '%s'", str);
             return -1;
         }
-        addr->ipv6 = addr->has_ipv6 = true;
     } else {
         /* hostname or IPv4 addr */
         if (sscanf(str, "%64[^:]:%32[^,]%n", host, port, &pos) != 2) {
             error_setg(errp, "error parsing address '%s'", str);
             return -1;
         }
-        if (host[strspn(host, "0123456789.")] == '\0') {
-            addr->ipv4 = addr->has_ipv4 = true;
-        }
     }
 
     addr->host = g_strdup(host);