Set EAI_SYSTEM only when h_errno is NETDB_INTERNAL

Fixes BZ #15339.

NSS_STATUS_UNAVAIL may mean that a necessary input resource is not
available.  This could occur in a number of cases including when the
network is down, system runs out of file descriptors, etc.  The
correct differentiator in such a case is the h_errno, which gives the
nature of failure.  In case of failures other than a simple 'not
found', we set h_errno as NETDB_INTERNAL and let errno be the
identifier for the exact error.
This commit is contained in:
Siddhesh Poyarekar 2013-05-21 21:54:41 +05:30
parent d5dd6189d5
commit 3d04f5db20
4 changed files with 26 additions and 10 deletions

View file

@ -1,3 +1,11 @@
2013-05-21 Siddhesh Poyarekar <siddhesh@redhat.com>
[BZ #15339]
* nss/getXXbyYY_r.c (REENTRANT_NAME): Set NETDB_INTERNAL only
when no services were used.
* sysdeps/posix/getaddrinfo.c (gaih_inet): Set h_errno.
Return EAI_SYSTEM if h_errno is NETDB_INTERNAL.
2013-05-21 Andreas Schwab <schwab@suse.de>
[BZ #15014]

8
NEWS
View file

@ -15,10 +15,10 @@ Version 2.18
14952, 14964, 14981, 14982, 14985, 14994, 14996, 15000, 15003, 15006,
15007, 15014, 15020, 15023, 15036, 15054, 15055, 15062, 15078, 15084,
15085, 15086, 15160, 15214, 15221, 15232, 15234, 15283, 15285, 15287,
15304, 15305, 15307, 15309, 15327, 15330, 15335, 15336, 15337, 15342,
15346, 15359, 15361, 15366, 15380, 15394, 15395, 15405, 15406, 15409,
15416, 15418, 15419, 15423, 15424, 15426, 15429, 15442, 15448, 15480,
15485, 15488, 15490, 15493, 15497.
15304, 15305, 15307, 15309, 15327, 15330, 15335, 15336, 15337, 15339,
15342, 15346, 15359, 15361, 15366, 15380, 15394, 15395, 15405, 15406,
15409, 15416, 15418, 15419, 15423, 15424, 15426, 15429, 15442, 15448,
15480, 15485, 15488, 15490, 15493, 15497.
* CVE-2013-0242 Buffer overrun in regexp matcher has been fixed (Bugzilla
#15078).

View file

@ -287,10 +287,10 @@ done:
#endif
*result = status == NSS_STATUS_SUCCESS ? resbuf : NULL;
#ifdef NEED_H_ERRNO
if (status == NSS_STATUS_UNAVAIL)
/* Either we failed to lookup the functions or the functions themselves
had a system error. Set NETDB_INTERNAL here to let the caller know
that the errno may have the real reason for failure. */
if (status == NSS_STATUS_UNAVAIL && !any_service && errno != ENOENT)
/* This happens when we weren't able to use a service for reasons other
than the module not being found. In such a case, we'd want to tell the
caller that errno has the real reason for failure. */
*h_errnop = NETDB_INTERNAL;
else if (status != NSS_STATUS_SUCCESS && !any_service)
/* We were not able to use any service. */

View file

@ -1036,7 +1036,15 @@ gaih_inet (const char *name, const struct gaih_service *service,
}
}
else
status = NSS_STATUS_UNAVAIL;
{
status = NSS_STATUS_UNAVAIL;
/* Could not load any of the lookup functions. Indicate
an internal error if the failure was due to a system
error other than the file not being found. We use the
errno from the last failed callback. */
if (errno != 0 && errno != ENOENT)
__set_h_errno (NETDB_INTERNAL);
}
}
if (nss_next_action (nip, status) == NSS_ACTION_RETURN)
@ -1050,7 +1058,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
_res.options |= old_res_options & RES_USE_INET6;
if (status == NSS_STATUS_UNAVAIL)
if (h_errno == NETDB_INTERNAL)
{
result = GAIH_OKIFUNSPEC | -EAI_SYSTEM;
goto free_and_return;