From: Ruediger Pluem Date: Tue, 25 Apr 2023 11:52:17 +0000 (+0000) Subject: * For retriggering a DNS lookup worker->cp->addr should be set to NULL and thus X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=dc498e9fde0efa2c968799cc295000d13104b82c;p=thirdparty%2Fapache%2Fhttpd.git * For retriggering a DNS lookup worker->cp->addr should be set to NULL and thus 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 --- diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c index 167d01d4e2d..be907af0789 100644 --- a/modules/proxy/proxy_util.c +++ b/modules/proxy/proxy_util.c @@ -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 */