summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuediger Pluem <rpluem@apache.org>2023-04-25 11:52:17 +0000
committerRuediger Pluem <rpluem@apache.org>2023-04-25 11:52:17 +0000
commitdc498e9fde0efa2c968799cc295000d13104b82c (patch)
treeea08057feb721edc2942e7eb9459df6f27344a0c
parentf3825febe88382eabd89837c90ca3284660d234a (diff)
downloadhttpd-dc498e9fde0efa2c968799cc295000d13104b82c.tar.gz
* 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
-rw-r--r--modules/proxy/proxy_util.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c
index 167d01d4e2..be907af078 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 */