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

Re: [patches] [bug] when /etc/hosts doesn't exist, apt fails to resolve hostnames using libc6 2.10.1



[This mail has been sent to the eglibc mailing list, but as it also
concerns the original GNU libc, I am CC:ing the libc-alpha mailing list.]

On Tue, Aug 04, 2009 at 08:09:44PM +0200, Matthias Klose wrote:
> [not a patch, but there's no way to subscribe to the bug tracker, and no 
> general ML; was told to use this list]
>
> forwarded from
>   https://launchpad.net/bugs/408901
>   http://bugs.debian.org/539950
>
> E.g. apt-get's call to getaddrinfo() returns with EAI_SYSTEM when 
> /etc/hosts is missing and EAI_NONAME if /etc/hosts is empty. This is 
> different from 2.9, where EAI_NONAME is returned in both cases, resulting 
> in the regression in apt-get. `sudo whoami' prints an additional error 
> message but works as expected otherwise.
>

I found strange finding such a bug report without more analysis on this
mailing list. Debian is listed here but we just get told about the bug a
couple of hours before.

So let's have a look at the code. getaddrinfo() calls gethostbyname4_r()
of libnss_files.so through dl_open(), and gets the error reporting by
the return values, but also by some of the arguments.

On the gethostbyname4_r() side (nss/nss_files/files-hosts.c), in case
/etc/hosts doesn't exists, internal_setent() returns -1, and the
function exits almost directly. In short, the errors arguments are not
modified, the behavior depends on an *unitialized variable*.

The patch below should fix this problem:

diff --git a/nss/nss_files/files-hosts.c b/nss/nss_files/files-hosts.c
index 7b69d47..e6e4576 100644
--- a/nss/nss_files/files-hosts.c
+++ b/nss/nss_files/files-hosts.c
@@ -423,6 +423,11 @@ _nss_files_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
       if (! keep_stream)
 	internal_endent ();
     }
+  else
+    {
+       *errnop = errno;
+       *herrnop = NETDB_INTERNAL;
+    }
 
   __libc_lock_unlock (lock);

It could be applied to both eglibc 2.9 and 2.10, and with it the
behavior of getaddrinfo() when /etc/hosts does not exist is the same
and does not depends on surrounding code which gives the value to the
unitialized variable.

Unfortunately with this patch the behavior is not the one that is
wanted, ie a functional getaddrinfo() when /etc/hosts does not exist.

-- 
Aurelien Jarno	                        GPG: 1024D/F1BCDB73
aurelien@xxxxxxxxxxx                 http://www.aurel32.net