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;
 }
 

Reply via email to