Bug 24816 - nss/tst-nss-files-hosts-long fails when no interface has AF_INET6 address (ie docker)
Summary: nss/tst-nss-files-hosts-long fails when no interface has AF_INET6 address (ie...
Status: RESOLVED FIXED
Alias: None
Product: glibc
Classification: Unclassified
Component: nss (show other bugs)
Version: 2.30
: P2 normal
Target Milestone: 2.37
Assignee: Florian Weimer
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-07-17 12:31 UTC by Romain Geissler
Modified: 2022-11-14 14:46 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed: 2022-09-13 00:00:00
fweimer: security-


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Romain Geissler 2019-07-17 12:31:19 UTC
Hi,

I am running the glibc build and test suite in a Docker container. Everything works, except the newly added nss/tst-nss-files-hosts-long which works for IPv4 but fails with IPv6. Even without long lines in /etc/hosts, getent always returns the exit code 2. After using "strace", it looks like "getent" fails before /etc/hosts is even opened, it fails after we receive the interfaces address from the socket AF_NETLINK which lists no AF_INET6 interfaces.

Also running this in docker confirms I have no ipv6 inside the container:

ubuntu@olaf:~> docker run --rm debian ip address
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
10: eth0@if11: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

I am testing this patch which I will submit if it works:

commit 9f580abbdc43b7f69dd8959ccf860f0f59bd167b (HEAD -> master)
Author: Romain Geissler <romain.geissler@amadeus.com>
Date:   Wed Jul 17 12:29:21 2019 +0000

    Fix nss/tst-nss-files-hosts-long.c when there is no IPv6 support.

diff --git a/nss/tst-nss-files-hosts-long.c b/nss/tst-nss-files-hosts-long.c
index 32f849e481b..aa79b88e41a 100644
--- a/nss/tst-nss-files-hosts-long.c
+++ b/nss/tst-nss-files-hosts-long.c
@@ -22,6 +22,31 @@
 #include <stdlib.h>
 #include <nss.h>
 #include <support/check.h>
+#include <ifaddrs.h>
+
+static int
+supports_inet_family(int family)
+{
+  struct ifaddrs *ifaddr, *ifa;
+  int ret = 0;
+
+  if (getifaddrs(&ifaddr) == -1)
+    FAIL_EXIT1("getifaddrs failed");
+
+  for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
+    if (ifa->ifa_addr == NULL)
+      continue;
+
+    if (ifa->ifa_addr->sa_family == family) {
+      ret = 1;
+      break;
+    }
+  }
+
+  freeifaddrs(ifaddr);
+
+  return ret;
+}

 static int
 do_test (void)
@@ -30,14 +55,20 @@ do_test (void)

   /* Run getent to fetch the IPv4 address for host test4.
      This forces /etc/hosts to be parsed.  */
-  ret = system("getent ahostsv4 test4");
-  if (ret != 0)
-    FAIL_EXIT1("ahostsv4 failed");
-
-  /* Likewise for IPv6.  */
-  ret = system("getent ahostsv6 test6");
-  if (ret != 0)
-    FAIL_EXIT1("ahostsv6 failed");
+  if (supports_inet_family(AF_INET))
+  {
+    ret = system("getent ahostsv4 test4");
+    if (ret != 0)
+      FAIL_EXIT1("ahostsv4 failed");
+  }
+
+    /* Likewise for IPv6.  */
+  if (supports_inet_family(AF_INET6))
+  {
+    ret = system("getent ahostsv6 test6");
+    if (ret != 0)
+      FAIL_EXIT1("ahostsv6 failed");
+  }

   exit (0);
 }

Cheers,
Romain
Comment 1 Florian Weimer 2019-07-17 13:26:29 UTC
FYI, I tested this against my own nss/tst-nss-files-hosts-long failure, and your patch does NOT fix that.  It would have been to easy. 8-(

But it looks this is a step in the right direction.  Would you please post the patch to the mailing list?  Thanks.
Comment 2 Xi Ruoyao 2021-08-30 18:44:37 UTC
(In reply to Florian Weimer from comment #1)
> FYI, I tested this against my own nss/tst-nss-files-hosts-long failure, and
> your patch does NOT fix that.  It would have been to easy. 8-(

I think the patch also need to check if ifa_addr is loopback.  getent sets AI_ADDRCONFIG so if the local system only has loopback addresses, it won't work.
Comment 3 Letu Ren 2022-06-10 17:01:07 UTC
I met this issue as well when building glibc v2.35 on ArchLinux RISC-V. The situation is just like the one described by Xi Ruoyao. The kernel of the board enables IPv6. There is only a loop back address in my system, no link local address. When debuging using gdb, I noticed getent() failed because getaddrinfo() returned EAI_NONAME.
Comment 4 Florian Weimer 2022-09-13 14:23:26 UTC
I've got a different patch that adds an option to getent to disable AI_ADDRCONFIG.
Comment 5 Florian Weimer 2022-09-13 14:49:02 UTC
Patches posted:

[PATCH 0/2] Fix nss/tst-nss-files-hosts-long on single-stack hosts (bug 24816)
<https://sourceware.org/pipermail/libc-alpha/2022-September/141958.html>
Comment 6 Florian Weimer 2022-09-20 11:33:24 UTC
Fixed for 2.37 via:

commit c75d20b5b27b0a60f0678236f51a4d3b0b058c00
Author: Florian Weimer <fweimer@redhat.com>
Date:   Tue Sep 13 16:11:40 2022 +0200

    nss: Fix tst-nss-files-hosts-long on single-stack hosts (bug 24816)
    
    getent implicitly passes AI_ADDRCONFIG to getaddrinfo by default.
    Use --no-addrconfig to suppress that, so that both IPv4 and IPv6
    lookups succeed even if the address family is not supported by the
    host.
    
    Reviewed-by: Carlos O'Donell <carlos@redhat.com>

commit a623f13adfac47c8634a7288e08f821a846bc650
Author: Florian Weimer <fweimer@redhat.com>
Date:   Tue Sep 13 16:10:20 2022 +0200

    nss: Implement --no-addrconfig option for getent
    
    The ahosts, ahostsv4, ahostsv6 commands unconditionally pass
    AI_ADDRCONFIG to getaddrinfo, which is not always desired.
    
    Reviewed-by: Carlos O'Donell <carlos@redhat.com>


I do not plan to backport this. Please advise if you need a backport to some branches.
Comment 7 Romain Geissler 2022-11-14 14:37:29 UTC
Hi,

From what I see, you backported this at least to branch 2.36, in commits 700d3281f9e57b53c27bc991394b22d467432626 and 2681d38cafaceafeb330bc0536fa710b75ed5947, thanks !

Cheers,
Romain
Comment 8 Florian Weimer 2022-11-14 14:46:36 UTC
Indeed, I think I backported this all the way to 2.34.