Bug 9981 - getaddrinfo(NULL) with AI_PASSIVE returns 0.0.0.0 (IPv4-only) and :: (IPv6+IPv4) in this order
Summary: getaddrinfo(NULL) with AI_PASSIVE returns 0.0.0.0 (IPv4-only) and :: (IPv6+IP...
Status: ASSIGNED
Alias: None
Product: glibc
Classification: Unclassified
Component: network (show other bugs)
Version: unspecified
: P2 normal
Target Milestone: ---
Assignee: Florian Weimer
URL:
Keywords:
: 14211 14967 (view as bug list)
Depends on:
Blocks:
 
Reported: 2009-03-22 23:28 UTC by Aurelien Jarno
Modified: 2018-03-31 12:50 UTC (History)
11 users (show)

See Also:
Host: x86_64-unknown-linux-gnu
Target: x86_64-unknown-linux-gnu
Build: x86_64-unknown-linux-gnu
Last reconfirmed:
fweimer: security-


Attachments
test program (947 bytes, text/x-csrc)
2009-03-22 23:29 UTC, Aurelien Jarno
Details
Don't sort passive localhost addresses, so that IPv6+IPvv4 remains first and IPv4-only, last (402 bytes, patch)
2014-05-31 00:52 UTC, Alexandre Oliva
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Aurelien Jarno 2009-03-22 23:28:51 UTC
The current getaddrinfo code prefers listening on ipv4-only instead of 
ipv4+ipv6 as previously. The gaitest.c file demonstrates the problem.

On a machine with both ipv4 and ipv6 connectivity, it returns:
        * ipv4 (only)
        * ipv6+ipv4

Listening for ipv6 connections never hurts, even if no one will ever
reach the server via ipv6.
Comment 1 Aurelien Jarno 2009-03-22 23:29:42 UTC
Created attachment 3835 [details]
test program
Comment 2 Aurelien Jarno 2009-05-01 09:57:31 UTC
I have just done a test build on the current CVS, and the bug is still present.
Comment 3 Aurelien Jarno 2009-05-01 10:47:28 UTC
The sort ipv4 and then ipv6 is done by rule 5, when matching the label.

It seems this rule should be ignored when dealing with wildcard addresses. 
Maybe got_source_addr should not be set to true for wildcard addresses.
Comment 4 Pavel Šimerda 2012-12-18 14:30:58 UTC
Comment from a newer duplicate:

 Pavel Šimerda 2012-12-16 16:08:35 UTC

On Linux, with net.ipv6.bindv6only = 0 (the default), getaddrinfo(NULL) with
AI_PASSIVE returns 0.0.0.0 and :: (in this order). AI_PASSIVE was meant to
return a list of addresses to listen on, but it is impossible to listen on
0.0.0.0 and :: at the same time, if :: implies dualstack mode.

Even the order is wrong, as listening on :: would work for both protocols,
while listening on 0.0.0.0 does not. If the order is fixed, applications could
just spit out a warning but still work correctly.

The only proper fix I can think of, is test for net.ipv6.bindv6only and return
only :: if this is 0, otherwise return both addresses (preferably IPv6 first).

Upstream bug report:

https://bugs.launchpad.net/ubuntu/+source/eglibc/+bug/673708

More information:

https://fedoraproject.org/wiki/Networking/NameResolution#Binding_to_the_INADDR_ANY_and.2For_in6addr_any_addresses

Cheers,

Pavel
Comment 5 Pavel Šimerda 2012-12-22 20:53:03 UTC
*** Bug 14211 has been marked as a duplicate of this bug. ***
Comment 6 Pavel Šimerda 2014-04-10 06:55:01 UTC
*** Bug 14967 has been marked as a duplicate of this bug. ***
Comment 7 Alexandre Oliva 2014-05-31 00:52:45 UTC
Created attachment 7624 [details]
Don't sort passive localhost addresses, so that IPv6+IPvv4 remains first and IPv4-only, last

I don't think it ever makes any sense for us to ever try to sort passive addresses: we always generate them IPv6+IPv4 first and IPv4-only last, with at most two adresses and possibly only one if we asked for a specific family.  Since the former is always preferred, it doesn't make sense to try to sort them.

The only doubt is whether to generate both when the first covers both; I'm not when dropping the latter is safe, so I'm leaving that unrelated decision out for now.

Any reason to not go with this patch?
Comment 8 Ondrej Bilka 2014-05-31 01:09:39 UTC
On Sat, May 31, 2014 at 12:52:45AM +0000, aoliva at sourceware dot org wrote:
> https://sourceware.org/bugzilla/show_bug.cgi?id=9981
> 
> Alexandre Oliva <aoliva at sourceware dot org> changed:
> 
>            What    |Removed                     |Added
> ----------------------------------------------------------------------------
>                  CC|                            |aoliva at sourceware dot org
> 
> --- Comment #7 from Alexandre Oliva <aoliva at sourceware dot org> ---
> Created attachment 7624 [details]
>   --> https://sourceware.org/bugzilla/attachment.cgi?id=7624&action=edit
> Don't sort passive localhost addresses, so that IPv6+IPvv4 remains first and
> IPv4-only, last
> 
> I don't think it ever makes any sense for us to ever try to sort passive
> addresses: we always generate them IPv6+IPv4 first and IPv4-only last, with at
> most two adresses and possibly only one if we asked for a specific family. 
> Since the former is always preferred, it doesn't make sense to try to sort
> them.
> 
> The only doubt is whether to generate both when the first covers both; I'm not
> when dropping the latter is safe, so I'm leaving that unrelated decision out
> for now.
> 
> Any reason to not go with this patch?
> 
Possible, you should send this to libc-alpha to get comments.
Comment 9 Simon Arlott 2014-05-31 11:20:58 UTC
> The only doubt is whether to generate both when the first covers both;
> I'm not when dropping the latter is safe, so I'm leaving that unrelated
> decision out for now.

It's not safe because the global sysctl net.ipv6.bindv6only could be set to 1 at any time, or the application could use IPV6_V6ONLY=1 on the socket (expecting to receive an IPv4 address too).
Comment 10 Pavel Šimerda 2014-05-31 17:56:40 UTC
(In reply to Simon Arlott from comment #9)
> It's not safe because the global sysctl net.ipv6.bindv6only could be set to
> 1 at any time, or the application could use IPV6_V6ONLY=1 on the socket
> (expecting to receive an IPv4 address too).

Do you see a better way?
Comment 11 Simon Arlott 2014-05-31 23:45:50 UTC
(In reply to Pavel Šimerda from comment #10)
> (In reply to Simon Arlott from comment #9)
> > It's not safe because the global sysctl net.ipv6.bindv6only could be set to
> > 1 at any time, or the application could use IPV6_V6ONLY=1 on the socket
> > (expecting to receive an IPv4 address too).
> 
> Do you see a better way?

There is nothing getaddrinfo() can do about this. It would have been better to not have the bindv6only sysctl and require an explicit IPV6_V6ONLY=0 on the socket, but it's too late for that now.
Comment 12 Pavel Šimerda 2014-06-01 09:26:21 UTC
(In reply to Simon Arlott from comment #11)
> There is nothing getaddrinfo() can do about this. It would have been better
> to not have the bindv6only sysctl and require an explicit IPV6_V6ONLY=0 on
> the socket, but it's too late for that now.

Then I would say we should assume bindv6only won't change between the call to getaddrinfo() and bind(). I know it's not 100% perfect but most systems don't change the setting at runtime at all. It certainly better than the current situation.
Comment 13 Simon Arlott 2014-06-01 09:35:29 UTC
(In reply to Pavel Šimerda from comment #12)
> Then I would say we should assume bindv6only won't change between the call
> to getaddrinfo() and bind(). I know it's not 100% perfect but most systems
> don't change the setting at runtime at all. It certainly better than the
> current situation.

You're making an assumption that the application hasn't been developed to work around this already. The default is usually bindv6only=0 in the sysctl but I've written code that sets the IPV6_V6ONLY=1 socket flag specifically so that all of the getaddrinfo() addresses will bind successfully.

I'd suggest documenting this non-AF-independent behaviour in the man page or pushing for an AF-independent "I'm using getaddrinfo() so don't try to second guess what I mean by bind()" socket flag.
Comment 14 Sourceware Commits 2014-11-07 09:20:29 UTC
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, lxoliva/getaddrinfo has been created
        at  d4139de660d1f25ad34ab023b13ec3cad78986d2 (commit)

- Log -----------------------------------------------------------------
https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=d4139de660d1f25ad34ab023b13ec3cad78986d2

commit d4139de660d1f25ad34ab023b13ec3cad78986d2
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Sun Jun 1 16:51:57 2014 -0300

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=91bbe1798129768e77cffecf324400fa4d31ad10

commit 91bbe1798129768e77cffecf324400fa4d31ad10
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Sun Jun 1 16:51:44 2014 -0300

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=bc3ac8b1779e8b180762841048601b90f469d6e5

commit bc3ac8b1779e8b180762841048601b90f469d6e5
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Sun Jun 1 16:48:15 2014 -0300

    for  ChangeLog
    
    	PR network/9981
    	* sysdeps/posix/getaddrinfo.c (getaddrinfo): Do not sort
    	AI_PASSIVE addresses.

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=7875573cbe52eabe78f1cab91c8a046d0bd5ed5a

commit 7875573cbe52eabe78f1cab91c8a046d0bd5ed5a
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Sat Sep 27 07:13:20 2014 -0300

    drop address family conversions from /etc/hosts parser
    
    for ChangeLog
    
    	* nss/nss_files/files-hosts.c (LINE_PARSER): Drop all address
    	family conversions.

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=393207b6a74aeed6227d88174b8b37e4ee095260

commit 393207b6a74aeed6227d88174b8b37e4ee095260
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Sat Sep 27 07:13:20 2014 -0300

    drop v4-to-v6 conversions of loopback addresses from /etc/hosts
    
    for ChangeLog
    
    	* nss/nss_files/files-hosts.c (LINE_PARSER): Drop family
    	conversion of loopback addresses from IPv4 to IPv6.

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=2e8a3341f470d8fa0dce69b8cf83e346a0017ada

commit 2e8a3341f470d8fa0dce69b8cf83e346a0017ada
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Sat Sep 27 07:13:18 2014 -0300

    drop v6-to-v4 conversions of loopback addresses from /etc/hosts
    
    for ChangeLog
    
    	* nss/nss_files/files-hosts.c (LINE_PARSER): Drop family
    	conversion of loopback addresses from IPv6 to IPv4.

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=901aad32edcbd1cfd57ee904ada6dcc56a53b385

commit 901aad32edcbd1cfd57ee904ada6dcc56a53b385
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Sat Sep 27 07:23:39 2014 -0300

    resolv: skip leading dot in domain to search
    
    This should only happen if the domain to search is the root,
    represented as . rather than by an empty string.  Skipping it here
    prevents libc_res_nquerydomain from duplicating the trailing dot,
    which would cause the domain name compression to fail.
    
    for  ChangeLog
    
    	PR 16469
    	* resolv/res_query.c (__libc_res_nsearch): Skip leading dot in
    	search domain names.

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=ba878d017e6b65f5d2880ac8262bc68224ee3a53

commit ba878d017e6b65f5d2880ac8262bc68224ee3a53
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Wed Oct 15 03:52:43 2014 -0300

    don't drop trailing dot in res_nquerydomain(..., name, NULL, ...)
    
    If we drop it here, we will fail to detect a duplicate trailing dot
    later on.  Retaining, OTOH, has no ill effects whatsoever, and it even
    saves us the trouble of copying the domain name minus the trailing
    dot, like we used to do.
    
    for ChangeLog
    
    	PR 16469
    	* resolv/res_query.c (__libc_res_nquerydomain): Retain
            trailing dot.
    	* NEWS: Fixes 16469.

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=ff9a1b7dce77c43235e11cda103698078cf44a45

commit ff9a1b7dce77c43235e11cda103698078cf44a45
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Mon Nov 3 18:51:40 2014 -0200

    Do not continue in nss_db_getservbyname

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=6286965b02069369beeb893833c34f01dc919ffb

commit 6286965b02069369beeb893833c34f01dc919ffb
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Mon Nov 3 18:51:40 2014 -0200

    create all sockets with SOCK_CLOEXEC

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=c83b8a87170cda275a5c591fe2a1d3657d2a6711

commit c83b8a87170cda275a5c591fe2a1d3657d2a6711
Author: Alexandre Oliva <aoliva@redhat.com>
Date:   Mon Nov 3 18:51:39 2014 -0200

    introduce internal function to ease poll retry with timeout

-----------------------------------------------------------------------
Comment 15 Carlos O'Donell 2016-11-26 16:23:48 UTC
Adding Florian Weimer to CC since this issue might be of interest to him as network subsystem maintainer.