From 2baf370c0a4dae4a934b3eefb8a2580dcb50649c Mon Sep 17 00:00:00 2001 From: Yann Ylavic Date: Mon, 29 Jan 2018 16:41:03 +0000 Subject: [PATCH] mod_proxy: fix proxy connection cleanup from an n+2 pool. When connection_destructor() is called after pchild is gone, we can't dereference worker->cp anymore. This happens is debug/one_process mode only, if we exit by calling apr_terminate() or clearing the process pool directly. Fix this by NULL-ing worker->cp in conn_pool_cleanup(), and by registering it as a pre_cleanup. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1822531 13f79535-47bb-0310-9956-ffa450edef68 --- modules/proxy/proxy_util.c | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c index 1418fc9a1c..d704dae37d 100644 --- a/modules/proxy/proxy_util.c +++ b/modules/proxy/proxy_util.c @@ -1306,10 +1306,7 @@ static void socket_cleanup(proxy_conn_rec *conn) static apr_status_t conn_pool_cleanup(void *theworker) { - proxy_worker *worker = (proxy_worker *)theworker; - if (worker->cp->res) { - worker->cp->pool = NULL; - } + ((proxy_worker *)theworker)->cp = NULL; return APR_SUCCESS; } @@ -1347,14 +1344,6 @@ static apr_status_t connection_cleanup(void *theconn) proxy_conn_rec *conn = (proxy_conn_rec *)theconn; proxy_worker *worker = conn->worker; - /* - * If the connection pool is NULL the worker - * cleanup has been run. Just return. - */ - if (!worker->cp->pool) { - return APR_SUCCESS; - } - if (conn->r) { apr_pool_destroy(conn->r->pool); conn->r = NULL; @@ -1476,7 +1465,7 @@ static apr_status_t connection_destructor(void *resource, void *params, proxy_worker *worker = params; /* Destroy the pool only if not called from reslist_destroy */ - if (worker->cp->pool) { + if (worker->cp) { proxy_conn_rec *conn = resource; apr_pool_destroy(conn->pool); } @@ -1907,9 +1896,8 @@ PROXY_DECLARE(apr_status_t) ap_proxy_initialize_worker(proxy_worker *worker, ser connection_constructor, connection_destructor, worker, worker->cp->pool); - apr_pool_cleanup_register(worker->cp->pool, (void *)worker, - conn_pool_cleanup, - apr_pool_cleanup_null); + apr_pool_pre_cleanup_register(worker->cp->pool, worker, + conn_pool_cleanup); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00930) "initialized pool in child %" APR_PID_T_FMT " for (%s) min=%d max=%d smax=%d",