On Wed, Sep 25, 2019 at 11:54 AM Stefan Eissing
<[email protected]> wrote:
>
> Looking for help on an issue in mod_watchdog use and child exits.
>
> Occasionally a httpd child crashes due to races between child pool being
> destroyed while watchdog threads are still running. The crash manifests most
> likely when OPENSSL_cleanup runs while another thread is generated a private
> key (singe that takes relatively long).
>
> Beside the crash report, nothing else really fails since the child is
> terminating anyway and no requests are onoing. But still, it's not a nice
> thing.
>
> Do you see an easy way to avoid this?
AFAICT, clean_child_exit() destroys pchild only, and pconf is still
alive at exit() time.
Couldn't we use pconf only in child_init hooks of mod_ssl and mod_watchdog?
Does something like the attached patch fixes the crash?
Index: include/http_main.h
===================================================================
--- include/http_main.h (revision 1866998)
+++ include/http_main.h (working copy)
@@ -52,6 +52,8 @@ AP_DECLARE_DATA extern const char *ap_runtime_dir;
AP_DECLARE_DATA extern server_rec *ap_server_conf;
/** global pool, for access prior to creation of server_rec */
AP_DECLARE_DATA extern apr_pool_t *ap_pglobal;
+/** configuration pool, cleared for each generation */
+AP_DECLARE_DATA extern apr_pool_t *ap_pconf;
/** state of the server (startup, exiting, ...) */
AP_DECLARE_DATA extern int ap_main_state;
/** run mode (normal, config test, config dump, ...) */
Index: server/config.c
===================================================================
--- server/config.c (revision 1866998)
+++ server/config.c (working copy)
@@ -62,6 +62,7 @@ AP_DECLARE_DATA const char *ap_server_root = NULL;
AP_DECLARE_DATA const char *ap_runtime_dir = NULL;
AP_DECLARE_DATA server_rec *ap_server_conf = NULL;
AP_DECLARE_DATA apr_pool_t *ap_pglobal = NULL;
+AP_DECLARE_DATA apr_pool_t *ap_pconf = NULL;
AP_DECLARE_DATA apr_array_header_t *ap_server_pre_read_config = NULL;
AP_DECLARE_DATA apr_array_header_t *ap_server_post_read_config = NULL;
Index: server/main.c
===================================================================
--- server/main.c (revision 1866998)
+++ server/main.c (working copy)
@@ -513,7 +513,7 @@ static void usage(process_rec *process)
process = init_process(&argc, &argv);
ap_pglobal = process->pool;
- pconf = process->pconf;
+ ap_pconf = pconf = process->pconf;
ap_server_argv0 = process->short_name;
ap_init_rng(ap_pglobal);
Index: modules/core/mod_watchdog.c
===================================================================
--- modules/core/mod_watchdog.c (revision 1866998)
+++ modules/core/mod_watchdog.c (working copy)
@@ -567,8 +567,8 @@ static void wd_child_init_hook(apr_pool_t *p, serv
"Watchdog: nothing configured?");
return;
}
- if ((wl = ap_list_provider_names(p, AP_WATCHDOG_PGROUP,
- AP_WATCHDOG_CVERSION))) {
+ if ((wl = ap_list_provider_names(wd_server_conf->pool, AP_WATCHDOG_PGROUP,
+ AP_WATCHDOG_CVERSION))) {
const ap_list_provider_names_t *wn;
int i;
wn = (ap_list_provider_names_t *)wl->elts;
Index: modules/ssl/ssl_engine_init.c
===================================================================
--- modules/ssl/ssl_engine_init.c (revision 1866998)
+++ modules/ssl/ssl_engine_init.c (working copy)
@@ -2159,14 +2159,15 @@ void ssl_init_Child(apr_pool_t *p, server_rec *s)
{
SSLModConfigRec *mc = myModConfig(s);
mc->pid = getpid(); /* only call getpid() once per-process */
+ (void)p;
/* XXX: there should be an ap_srand() function */
srand((unsigned int)time(NULL));
/* open the mutex lockfile */
- ssl_mutex_reinit(s, p);
+ ssl_mutex_reinit(s, ap_pconf);
#ifdef HAVE_OCSP_STAPLING
- ssl_stapling_mutex_reinit(s, p);
+ ssl_stapling_mutex_reinit(s, ap_pconf);
#endif
}