[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

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: