]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
* For retriggering a DNS lookup worker->cp->addr should be set to NULL and thus
authorRuediger Pluem <rpluem@apache.org>
Tue, 25 Apr 2023 11:52:17 +0000 (11:52 +0000)
committerRuediger Pluem <rpluem@apache.org>
Tue, 25 Apr 2023 11:52:17 +0000 (11:52 +0000)
  we need to avoid a race that worker->cp->addr switches to NULL after we
  checked it to be non NULL but before we assign it to conn->addr in an else
  tree which would leave conn->addr to NULL and likely cause a segfault later.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1909400 13f79535-47bb-0310-9956-ffa450edef68

modules/proxy/proxy_util.c

index 167d01d4e2df67b5394072b0865dcfea51198830..be907af07897383e21c46e14cf0861b6806acce0 100644 (file)
@@ -2761,8 +2761,16 @@ ap_proxy_determine_connection(apr_pool_t *p, request_rec *r,
             /*
              * Looking up the backend address for the worker only makes sense if
              * we can reuse the address.
+             *
+             * As we indicate in the comment below that for retriggering a DNS
+             * lookup worker->cp->addr should be set to NULL we need to avoid
+             * a race that worker->cp->addr switches to NULL after we checked
+             * it to be non NULL but before we assign it to conn->addr in an
+             * else tree which would leave it to NULL and likely cause a
+             * segfault later.
              */
-            if (!worker->cp->addr) {
+            conn->addr = worker->cp->addr;
+            if (!conn->addr) {
                 if ((err = PROXY_THREAD_LOCK(worker)) != APR_SUCCESS) {
                     ap_log_rerror(APLOG_MARK, APLOG_ERR, err, r, APLOGNO(00945) "lock");
                     return HTTP_INTERNAL_SERVER_ERROR;
@@ -2772,7 +2780,8 @@ ap_proxy_determine_connection(apr_pool_t *p, request_rec *r,
                  * Recheck addr after we got the lock. This may have changed
                  * while waiting for the lock.
                  */
-                if (!AP_VOLATILIZE_T(apr_sockaddr_t *, worker->cp->addr)) {
+                conn->addr = AP_VOLATILIZE_T(apr_sockaddr_t *, worker->cp->addr);
+                if (!conn->addr) {
 
                     apr_sockaddr_t *addr;
 
@@ -2786,16 +2795,13 @@ ap_proxy_determine_connection(apr_pool_t *p, request_rec *r,
                                                 conn->hostname, APR_UNSPEC,
                                                 conn->port, 0,
                                                 worker->cp->dns_pool);
+                    conn->addr = addr;
                     worker->cp->addr = addr;
                 }
-                conn->addr = worker->cp->addr;
                 if ((uerr = PROXY_THREAD_UNLOCK(worker)) != APR_SUCCESS) {
                     ap_log_rerror(APLOG_MARK, APLOG_ERR, uerr, r, APLOGNO(00946) "unlock");
                 }
             }
-            else {
-                conn->addr = worker->cp->addr;
-            }
         }
     }
     /* Close a possible existing socket if we are told to do so */