Bug 20612 - getaddrinfo() returns EAI_SYSTEM depending on uninitialized value
Summary: getaddrinfo() returns EAI_SYSTEM depending on uninitialized value
Status: RESOLVED MOVED
Alias: None
Product: glibc
Classification: Unclassified
Component: nss (show other bugs)
Version: 2.24
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-09-15 14:04 UTC by Martin Panter
Modified: 2016-09-17 08:26 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:
fweimer: security-


Attachments
Demo, compiled with c99 t.c (339 bytes, text/x-csrc)
2016-09-15 14:04 UTC, Martin Panter
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Panter 2016-09-15 14:04:10 UTC
Created attachment 9512 [details]
Demo, compiled with c99 t.c

On x86-64 Arch Linux, I have /usr/lib/libnss_wins.so.2 installed from the smbclient 4.5.0 package. I have enabled it by adding “wins” to the end of the “hosts” line in /etc/nsswitch.conf:

hosts: files dns myhostname wins

Running the attached program can get getaddrinfo() to quickly return EAI_SYSTEM, without actually setting errno. In other cases, getaddrinfo() has a short delay before returning, and returns EAI_NONAME, which seems to be the normal behaviour. I always seem to get the normal behaviour on a 32-bit x86 computer. I can also trigger the normal behaviour by changing the f(0xFF) call to f(0x00), although valgrind still reports uninitialized value errors.

Eg of incorrect output:
$ c99 t.c
$ valgrind ./a.out
==13182== Memcheck, a memory error detector
==13182== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==13182== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==13182== Command: ./a.out
==13182== 
==13182== Conditional jump or move depends on uninitialised value(s)
==13182==    at 0x4F09FCD: gaih_inet.constprop.5 (in /usr/lib/libc-2.24.so)
==13182==    by 0x4F0A177: getaddrinfo (in /usr/lib/libc-2.24.so)
==13182==    by 0x4006FD: main (in /media/disk/home/proj/python/cpython/a.out)
==13182== 
getaddrinfo() -> -11 System error (errno = 0 Success)
. . .
[Exit 1]
Comment 1 Martin Panter 2016-09-15 14:11:42 UTC
In an attempt to eliminate the wins plugin from the picture, I tried to make my own dummy NSS plugin:

$ cat n.c
#include <nss.h>
#include <stddef.h>
#include <netdb.h>

enum nss_status _nss_wtf_gethostbyname2_r(const char *name, int af,
        struct hostent *he, char *buffer, size_t buflen, int *h_errnop) {
    *h_errnop = NO_DATA;
    return NSS_STATUS_UNAVAIL;
}
$ gcc -shared n.c -o libnss_wtf.so.2
$ sudo cp libnss_wtf.so.2 /lib/

nsswitch.conf modified to read:

hosts: files dns myhostname wtf

The same problem occurs with the above plugin instead of wins.

BTW there are other bugs that I found that may be related, but I wasn’t sure:
https://sourceware.org/bugzilla/show_bug.cgi?id=10021
https://sourceware.org/bugzilla/show_bug.cgi?id=15272
Comment 2 Florian Weimer 2016-09-16 12:33:47 UTC
(In reply to Martin Panter from comment #1)
> enum nss_status _nss_wtf_gethostbyname2_r(const char *name, int af,
>         struct hostent *he, char *buffer, size_t buflen, int *h_errnop) {


That function definition is incorrect, it should be:

enum nss_status
_nss_wtf_gethostbyname2_r (const char *name, int af, struct hostent *host,
                           char *buffer, size_t buflen, int *errnop,
                           int *h_errnop)

In effect, you are never updating *h_errnop (only *errnop), so the valgrind warning is appropriate here.
Comment 3 Florian Weimer 2016-09-16 12:41:38 UTC
nss_wins in Samba 4.5.0 has this:

NSS_STATUS _nss_wins_gethostbyname_r(const char *hostname, struct hostent *he,
                          char *buffer, size_t buflen, int *h_errnop);
NSS_STATUS _nss_wins_gethostbyname2_r(const char *name, int af, struct hostent *he,
                           char *buffer, size_t buflen, int *h_errnop);

So this is a Samba bug.  I reported it here:

  https://bugzilla.samba.org/show_bug.cgi?id=12269