Hi,
attached patch (against 1.4.6, but works with trunk too) fixes two
problems I have found in call_resolver function.
1. For unknown reason (probably getaddrinfo bug), getaddrinfo returns
error EAI_SYSTEM, but errno is set to 0. In this case, we return 0
(APR_SUCCESS) from call_resolver even when this function failed. This
leads to httpd crash later, because *sa is NULL, but we return APR_SUCCESS.
Attached patch fixes it by returning APR_EGENERAL in this case.
I was not able to reproduce it myself, but it happens for one Fedora
user [1]. I have already reported this behaviour to glibc devs and I'm
waiting for the response now.
2. "while" loop in the same function skips some results retuned by
getaddrinfo. Theoretically, this part of code can skip all results
returned by getaddrinfo, so *sa will be NULL, but after this loop, we
return APR_SUCCESS without checking for this case.
Attached patch fixes it by returning APR_EGENERAL in this case.
[1] https://bugzilla.redhat.com/show_bug.cgi?id=954007
Regards,
Jan Kaluza
diff --git a/network_io/unix/sockaddr.c b/network_io/unix/sockaddr.c
index ed4c474..094da2c 100644
--- a/network_io/unix/sockaddr.c
+++ b/network_io/unix/sockaddr.c
@@ -367,7 +367,7 @@ static apr_status_t call_resolver(apr_sockaddr_t **sa,
return apr_get_netos_error();
#else
if (error == EAI_SYSTEM) {
- return errno;
+ return errno ? errno : APR_EGENERAL;
}
else
{
@@ -422,6 +422,13 @@ static apr_status_t call_resolver(apr_sockaddr_t **sa,
ai = ai->ai_next;
}
freeaddrinfo(ai_list);
+
+ /* getaddrinfo returned only useless entries and *sa is still empty.
+ * This should be treated as an error. */
+ if (*sa == NULL) {
+ return APR_EGENERAL;
+ }
+
return APR_SUCCESS;
}