Bug 14212

Summary: getaddrinfo() with multiple results from /etc/hosts and AF_INET6 in hints fails when /etc/hosts.conf:multi=off
Product: glibc Reporter: Mike Frysinger <vapier>
Component: networkAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED FIXED    
Severity: normal CC: aoliva, siddhesh
Priority: P2 Flags: fweimer: security-
Version: 2.15   
Target Milestone: ---   
Host: Target:
Build: Last reconfirmed:
Attachments: getaddrinfo test

Description Mike Frysinger 2012-06-09 05:15:17 UTC
Created attachment 6444 [details]
getaddrinfo test

i have these /etc settings:

$ cat /etc/hosts
127.0.0.1   localhost
::1         localhost

$ cat /etc/host.conf 
order hosts, bind
multi off

trying to do getaddrinfo("localhost") when hints is just set to ai_family=AF_INET6 fails with EAI_NODATA when it should have returned ::1

if i change multi on, then i get back ::1 as expected

if i also use ai_flags=AI_V4MAPPED, then multi off gives me ::ffff:127.0.0.1 -- which is correct, just pointing out that it seems to be matching the first result and then aborting because the hints didn't line up

see attached code:
$ gcc getaddrinfo.c && ./a.out localhost
Comment 1 Siddhesh Poyarekar 2013-04-15 13:11:27 UTC
I cannot reproduce this with latest master.

$ cat /etc/hosts
127.0.0.1   localhost
::1         localhost

$ cat /etc/host.conf
order hosts, bind
multi off

$ ./a.out localhost
this is an IPv6 result
this is an IPv6 result
this is an IPv6 result
Comment 2 Alexandre Oliva 2014-09-27 05:51:00 UTC
This was fixed, apparently by accident, with the patch for bug 14505, commit 8479f23aa1.  It disabled the use of the nss gethostbyname4 interface for non-AF_UNSPEC queries.  Without the patch, we'd use gethostbyname4, get only the
IPv4 address from the hosts plugin (because multi is off, and gethostbyname4 doesn't know what address family we're looking for), and discard that address as unsuitable.  With the patch, we use gethostbyname2 to look up IPv6 addresses only.  It doesn't perform V4MAPPED conversions, for the hconf flag that would do so is explicitly cleared by getaddrinfo, that would look up IPv4 addresses separately afterwards in case of no IPv6 matches.