Bug#952740: glibc: getaddrinfo with AI_ADDRCONFIG and AF_INET[6] can't resolve localhost in an isolated network namespace
Package: libc6
Version: 2.29-10
Severity: normal
Summarizing the glibc bits of #948834, which I'm about to close because
newer versions of glib2.0 bypass it:
Steps to reproduce
==================
- Be in an environment with only loopback addresses. Using bubblewrap and
`bwrap --unshare-net --dev-bind / / ./getaddrinfo` is one way to make
this happen; building in pbuilder is another.
- Have nsswitch configured in such a way that localhost "should" resolve
to 127.0.0.1 and/or ::1, for example by installing netbase to get
the typical /etc/hosts, or by installing libnss-myhostname.
- Have a program that resolves names with AI_ADDRCONFIG, which is
often considered to be a good idea. For example,
glib2.0's GResolver or dbus' support for TCP addresses.
https://bugs.debian.org/cgi-bin/bugreport.cgi?att=1;bug=948834;filename=getaddrinfo.c;msg=30
is a convenient way to try this out.
- Attempt to resolve the reserved name "localhost" with the AI_ADDRCONFIG
flag and the AF_INET or AF_INET6 family. (The family not being AF_UNSPEC
is significant, due to #854301.)
Expected result
===============
localhost resolves to 127.0.0.1 or to ::1, as appropriate for the family.
Actual result
=============
-2 "Name or service not known"
Impact
======
Packages whose regression tests connect to localhost by name FTBFS when
built in pbuilder (but not sbuild or a typical development environment).
This currently affects glib2.0 2.62.x, but not 2.64.x (#948834) and in
the past it affected dbus (#897662).
Developers who expect resolving localhost to succeed become confused
about the layer in which it fails (e.g. expecting the problem to be with
/etc/hosts).
Workarounds that other packages can use
=======================================
- Implement
<https://tools.ietf.org/html/draft-ietf-dnsop-let-localhost-be-localhost-02>
in higher-level resolver APIs (for example glib2.0 >= 2.63.1, recent
Firefox and recent Chromium do this)
- Implement a special case where AI_ADDRCONFIG is not used for "localhost"
(for example Firefox has done this for a long time)
- Use AF_UNSPEC (or hints == NULL), and hope #854301 doesn't ever get fixed
- Don't use AI_ADDRCONFIG (generates unnecessary DNS traffic, and
potentially causes connection delays depending on application behaviour,
for single-stack hosts)
- On name resolution failure with AI_ADDRCONFIG, retry without AI_ADDRCONFIG
before giving up
- Configure a useless non-127.0.0.1 IP address inside network namespaces
(perhaps 127.0.0.2?) to trick AI_ADDRCONFIG into thinking we have IPv4
connectivity
- Make tests that require resolving localhost skip themselves if it
doesn't resolve; or don't run such tests at build-time at all, only in
autopkgtest
(IMO undesirable because it significantly reduces test coverage on
non-amd64, non-arm64 architectures, where the buildds are our only
opportunity to check that the built package is functional)
Possible solutions in glibc
===========================
- Implement a localhost special-case resembling
<https://tools.ietf.org/html/draft-ietf-dnsop-let-localhost-be-localhost-02>
at the getaddrinfo() level, before checking AI_ADDRCONFIG
- Implement a localhost special-case that ignores AI_ADDRCONFIG, but then
delegates to NSS modules as usual
- Instead of implementing AI_ADDRCONFIG at the getaddrinfo() level, pass
it down to NSS modules, make the dns module respect it (only send DNS
A/AAAA requests if we have at least one non-local IPv4/IPv6 address),
and make non-DNS modules like files and myhostname ignore it
- Reject this as not a glibc bug, and recommend that libraries and
applications use one of the above workarounds
(suggestions on which ones are the best workarounds welcome!)
Related glibc bug reports
=========================
- https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=854301 points out that
the getaddrinfo() specification implies that AF_UNSPEC should arguably
also fail in the same way
- https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=854302 points out that
AI_ADDRCONFIG is not necessarily great to have as a default, for this
reason
- https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=780294 requests that
IPv6 link-local addresses should be ignored for the purposes of
AI_ADDRCONFIG
- https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=801362 requests that
foo.localhost (for all values of foo) should always resolve to 127.0.0.1
and/or ::1 at the getaddrinfo() level, which would avoid this
References outside Debian
=========================
- https://fedoraproject.org/wiki/QA/Networking/NameResolution/ADDRCONFIG
- https://sourceware.org/bugzilla/show_bug.cgi?id=12377
- https://github.com/zeromq/libzmq/issues/42
Reply to: