Bug 2167468

Summary: systemd: _nss_myhostname_gethostbyname2_r in nss_myhostname returns NSS_STATUS_SUCCESS without any addresses
Product: Red Hat Enterprise Linux 9 Reporter: Pino Toscano <ptoscano>
Component: systemdAssignee: Lukáš Nykrýn <lnykryn>
Status: CLOSED ERRATA QA Contact: Frantisek Sumsal <fsumsal>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: 9.2CC: ashankar, codonell, dj, dtardon, fweimer, mnewsome, pfrankli, sipoyare, skolosov, systemd-maint-list, yuwatana
Target Milestone: rcKeywords: Regression, Triaged
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: systemd-252-5.el9 Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2023-05-09 08:22:35 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Attachments:
Description Flags
Sample getaddrinfo() program
none
/etc/nsswitch.conf none

Description Pino Toscano 2023-02-06 17:31:11 UTC
Created attachment 1942561 [details]
Sample getaddrinfo() program

Created attachment 1942561 [details]
Sample getaddrinfo() program

Description of problem:
getaddrinfo() crashes in case the system has no IPv6 (disabled via sysctl calls), and the hints have ai_family=AF_INET6;

Version-Release number of selected component (if applicable):
glibc-2.34-58.el9.x86_64
systemd-252-3.el9.x86_64

How reproducible:
Every time

Steps to Reproduce:
1. build the attached getaddressinfo-test.c
2. disable IPv6 on the system:
  sudo sysctl -w net.ipv6.conf.all.disable_ipv6=1
  sudo sysctl -w net.ipv6.conf.default.disable_ipv6=1
2. run it specifying the hostname of the system, e.g. ./getaddressinfo-test `hostname`

Actual results:
The sample getaddressinfo-test exits with segmentation fault.

Expected results:
getaddressinfo-test runs fine, and either
- exits with a "getaddrinfo: " error line (expected, since IPv6 is not available)
- return something (?)

Additional info:
Attached also the /etc/nsswitch.conf of the system.

Comment 1 Pino Toscano 2023-02-06 17:32:03 UTC
Created attachment 1942562 [details]
/etc/nsswitch.conf

Comment 2 Florian Weimer 2023-02-06 17:48:16 UTC
I can reproduce it in Beaker, on a machine where nss_dns does not succeed for its host name, but _nss_myhostname_gethostbyname2_r does:

Run till exit from #0  _nss_myhostname_gethostbyname2_r (
    name=name@entry=0x7fffffffe201 "<redacted>", 
    af=af@entry=10, host=host@entry=0x7fffffffd630, buffer=0x7fffffffd920 "", 
    buflen=1024, errnop=errnop@entry=0x7ffff7fb56c0, h_errnop=0x7ffff7fb5724)
    at ../src/nss-myhostname/nss-myhostname.c:520
0x00007ffff7d36d8d in gaih_inet (name=<optimized out>, 
    name@entry=0x7fffffffe201 "<redacted>", 
    service=service@entry=0x0, req=req@entry=0x7fffffffdd90, 
    pai=pai@entry=0x7fffffffd818, naddrs=naddrs@entry=0x7fffffffd814, 
    tmpbuf=tmpbuf@entry=0x7fffffffd910) at ../sysdeps/posix/getaddrinfo.c:832
832				  gethosts (AF_INET6, struct in6_addr);
Value returned is $5 = NSS_STATUS_SUCCESS

Looking at the result in convert_hostent_to_gaih_addrtuple (the macro goo makes that a bit difficult to debug), I get:

convert_hostent_to_gaih_addrtuple (req=req@entry=0x7fffffffdd90,
    family=family@entry=10, h=h@entry=0x7fffffffd630,
    result=result@entry=0x7fffffffd618) at ../sysdeps/posix/getaddrinfo.c:201
(gdb) print *h
$13 = {h_name = 0x7fffffffd920 "<redacted>",
  h_aliases = 0x7fffffffd958, h_addrtype = 10, h_length = 16,
  h_addr_list = 0x7fffffffd968}
(gdb) print h->h_addr_list
$14 = (char **) 0x7fffffffd968
(gdb) print h->h_addr_list[0]
$15 = 0x0

So nss_myhostname returns NSS_STATUS_SUCCESS, but no data. The more usual return value for this is NSS_STATUS_TRYAGAIN, telling glibc NSS to continue processing with the next service module. I am not sure if the current protocol actually offers an authoritative NODATA response.

Assuming this analysis is correct, this is more of a systemd bug than a glibc bug.

Comment 3 Florian Weimer 2023-02-07 16:45:19 UTC
If you get a machine out of Beaker that has an IPv6 address, you can trigger this bug via:

hostnamectl hostname mycomputer

And then use “mycomputer” with the reproducer.

I cannot reproduce the issue with:

systemd-250-12.el9_1.2.x86_64
systemd-libs-250-12.el9_1.2.x86_64
systemd-pam-250-12.el9_1.2.x86_64
systemd-rpm-macros-250-12.el9_1.2.noarch
systemd-udev-250-12.el9_1.2.x86_64

I can reproduce the issue with:

systemd-252-4.el9.x86_64
systemd-libs-252-4.el9.x86_64
systemd-pam-252-4.el9.x86_64
systemd-rpm-macros-252-4.el9.noarch
systemd-udev-252-4.el9.x86_64

I suspect it is a side effect of:

commit db50d326a46beca3cc24b6354b6e1b3591902d45
Author: Yu Watanabe <watanabe.yu+github>
Date:   Fri Apr 22 10:31:22 2022 +0900

    nss-myhostname: do not return IPv6 local address if IPv6 is disabled

This came with the systemd-252 rebase.

Comment 4 Yu Watanabe 2023-02-08 21:35:00 UTC
Thank you for the report. Fix is waiting in https://github.com/systemd/systemd/pull/26366.

Comment 6 Plumber Bot 2023-02-10 09:12:01 UTC
fix merged to github main branch -> https://github.com/redhat-plumbers/systemd-rhel9/pull/137

Comment 11 errata-xmlrpc 2023-05-09 08:22:35 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory (systemd bug fix and enhancement update), and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://access.redhat.com/errata/RHBA-2023:2531