Bug#557596: gaih_inet logic for summarizing gethostbyname4_r results broken
Package: eglibc
Version: 2.10.1-7
Severity: important
Tags: patch
NSS plugins wishing to provide data to programs calling getaddrinfo() must
implement two procedures named:
_nss_<foo>_gethostbyname4_r() and
_nss_<foo>_gethostbyname2_r().
The function gaih_inet() in libc dynamically loads and calls these procedures
and then attempts to combine the results from all available plugins.
Unfortunately, in the following scenario, the combination step is performed
incorrectly:
1. Install your NSS plugin so that it is called after the
libnss_dns-2.10.1.so plugin.
2. Remove your default route.
3. Call getaddrinfo(NODE, SERVICE, NULL, &results).
The problem is that the third call, internally, results in a call to
_nss_dns_gethostbyname4_r()
which returns NSS_STATUS_UNAVAIL with herrno = TRY_AGAIN. This combination of
return and error codes causes gaih_inet()'s logic to set
no_data = -3.
This variable is used to signal to the rest of the gaih_inet procedure that no
results are available.
Unfortunately, when your plugin returns NSS_STATUS_SUCCESS and sets herrno =
NETDB_SUCCESS, your plugin's results will be *ignored* because gaih_inet
exits its loop without resetting no_data.
The attached patch fixes the problem for me. The patch was tested with code
from http://wiki.laptop.org/go/Dnshash.
-- System Information:
Debian Release: squeeze/sid
APT prefers stable
APT policy: (700, 'stable'), (600, 'unstable'), (500, 'experimental')
Architecture: i386 (i686)
Kernel: Linux 2.6.30-2-686 (SMP w/1 CPU core)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash
--- a/sysdeps/posix/getaddrinfo.c 2009-11-22 16:21:19.000000000 -0500
+++ b/sysdeps/posix/getaddrinfo.c 2009-11-22 16:28:26.000000000 -0500
@@ -715,7 +715,10 @@ gaih_inet (const char *name, const struc
tmpbuflen, &rc, &herrno,
NULL));
if (status == NSS_STATUS_SUCCESS)
- break;
+ {
+ no_data = 0;
+ break;
+ }
if (status != NSS_STATUS_TRYAGAIN
|| rc != ERANGE || herrno != NETDB_INTERNAL)
{
Reply to: