aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/posix
diff options
context:
space:
mode:
authorFlorian Weimer <fweimer@redhat.com>2017-09-04 11:27:24 +0200
committerFlorian Weimer <fweimer@redhat.com>2017-09-04 11:44:22 +0200
commita71a3374cd8cf53776c33994f69ec184c26f2129 (patch)
tree6e778554ebc5df4a89b0612524a2925a730614f0 /sysdeps/posix
parent7966331555df43bb7e2a55ce5a17a330e57f487f (diff)
getaddrinfo: Fix error handling in gethosts [BZ #21915] [BZ #21922]
The old code uses errno as the primary indicator for success or failure. This is wrong because errno is only set for specific combinations of the status return value and the h_errno variable. (cherry picked from commit f4a6be2582b8dfe8adfa68da3dd8decf566b3983)
Diffstat (limited to 'sysdeps/posix')
-rw-r--r--sysdeps/posix/getaddrinfo.c42
1 files changed, 20 insertions, 22 deletions
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
index 0cf87c224d..2c4b6d6793 100644
--- a/sysdeps/posix/getaddrinfo.c
+++ b/sysdeps/posix/getaddrinfo.c
@@ -242,28 +242,26 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req,
#define gethosts(_family, _type) \
{ \
struct hostent th; \
- struct hostent *h; \
char *localcanon = NULL; \
no_data = 0; \
- while (1) { \
- status = DL_CALL_FCT (fct, (name, _family, &th, \
- tmpbuf->data, tmpbuf->length, \
- &errno, &h_errno, NULL, &localcanon)); \
- if (errno != ERANGE || h_errno != NETDB_INTERNAL) \
- break; \
- if (!scratch_buffer_grow (tmpbuf)) \
- { \
- __resolv_context_enable_inet6 (res_ctx, res_enable_inet6); \
- __resolv_context_put (res_ctx); \
- result = -EAI_MEMORY; \
- goto free_and_return; \
- } \
- } \
- if (status == NSS_STATUS_SUCCESS && errno == 0) \
- h = &th; \
- else \
- h = NULL; \
- if (errno != 0) \
+ while (1) \
+ { \
+ status = DL_CALL_FCT (fct, (name, _family, &th, \
+ tmpbuf->data, tmpbuf->length, \
+ &errno, &h_errno, NULL, &localcanon)); \
+ if (status != NSS_STATUS_TRYAGAIN || h_errno != NETDB_INTERNAL \
+ || errno != ERANGE) \
+ break; \
+ if (!scratch_buffer_grow (tmpbuf)) \
+ { \
+ __resolv_context_enable_inet6 (res_ctx, res_enable_inet6); \
+ __resolv_context_put (res_ctx); \
+ result = -EAI_MEMORY; \
+ goto free_and_return; \
+ } \
+ } \
+ if (status == NSS_STATUS_NOTFOUND \
+ || status == NSS_STATUS_TRYAGAIN || status == NSS_STATUS_UNAVAIL) \
{ \
if (h_errno == NETDB_INTERNAL) \
{ \
@@ -277,9 +275,9 @@ convert_hostent_to_gaih_addrtuple (const struct addrinfo *req,
else \
no_data = h_errno == NO_DATA; \
} \
- else if (h != NULL) \
+ else if (status == NSS_STATUS_SUCCESS) \
{ \
- if (!convert_hostent_to_gaih_addrtuple (req, _family,h, &addrmem)) \
+ if (!convert_hostent_to_gaih_addrtuple (req, _family, &th, &addrmem)) \
{ \
__resolv_context_enable_inet6 (res_ctx, res_enable_inet6); \
__resolv_context_put (res_ctx); \