[apache2] 05/09: Fix Apache crash on restarts (ASF Bug 61558)
Ondřej Surý
ondrej at debian.org
Tue Oct 24 18:36:01 UTC 2017
This is an automated email from the git hooks/post-receive script.
ondrej pushed a commit to branch master
in repository apache2.
commit b85d6b526aa2978ce318f1a15bdcaba39f79631f
Author: Ondřej Surý <ondrej at sury.org>
Date: Thu Sep 28 17:53:26 2017 +0200
Fix Apache crash on restarts (ASF Bug 61558)
---
...-hooks-cleanup-on-exit-v3-2.4.x-for-bug-6.patch | 228 +++++++++++++++++++++
debian/patches/series | 1 +
2 files changed, 229 insertions(+)
diff --git a/debian/patches/0011-Signals-and-hooks-cleanup-on-exit-v3-2.4.x-for-bug-6.patch b/debian/patches/0011-Signals-and-hooks-cleanup-on-exit-v3-2.4.x-for-bug-6.patch
new file mode 100644
index 0000000..99d0a31
--- /dev/null
+++ b/debian/patches/0011-Signals-and-hooks-cleanup-on-exit-v3-2.4.x-for-bug-6.patch
@@ -0,0 +1,228 @@
+From: =?utf-8?q?Ond=C5=99ej_Sur=C3=BD?= <ondrej at sury.org>
+Date: Thu, 28 Sep 2017 17:51:59 +0200
+Subject: Signals and hooks cleanup on exit (v3, 2.4.x) for bug #61558
+
+---
+ os/unix/unixd.c | 24 ++++++++++++++++++++++++
+ server/main.c | 33 ++++++++++++++++++++++++++++-----
+ server/mpm/event/event.c | 3 ---
+ server/mpm/prefork/prefork.c | 3 ---
+ server/mpm/worker/worker.c | 3 ---
+ server/mpm_unix.c | 29 +++++++++++++++++++++++++++++
+ 6 files changed, 81 insertions(+), 14 deletions(-)
+
+diff --git a/os/unix/unixd.c b/os/unix/unixd.c
+index 07a9bef..7f71d1a 100644
+--- a/os/unix/unixd.c
++++ b/os/unix/unixd.c
+@@ -437,11 +437,19 @@ AP_DECLARE(apr_status_t) ap_unixd_accept(void **accepted, ap_listen_rec *lr,
+ /* Unixes MPMs' */
+
+ static ap_unixd_mpm_retained_data *retained_data = NULL;
++static apr_status_t retained_data_cleanup(void *unused)
++{
++ (void)unused;
++ retained_data = NULL;
++ return APR_SUCCESS;
++}
++
+ AP_DECLARE(ap_unixd_mpm_retained_data *) ap_unixd_mpm_get_retained_data()
+ {
+ if (!retained_data) {
+ retained_data = ap_retained_data_create("ap_unixd_mpm_retained_data",
+ sizeof(*retained_data));
++ apr_pool_pre_cleanup_register(ap_pglobal, NULL, retained_data_cleanup);
+ retained_data->mpm_state = AP_MPMQ_STARTING;
+ }
+ return retained_data;
+@@ -449,6 +457,10 @@ AP_DECLARE(ap_unixd_mpm_retained_data *) ap_unixd_mpm_get_retained_data()
+
+ static void sig_term(int sig)
+ {
++ if (!retained_data) {
++ /* Main process (ap_pglobal) is dying */
++ return;
++ }
+ retained_data->mpm_state = AP_MPMQ_STOPPING;
+ if (retained_data->shutdown_pending
+ && (retained_data->is_ungraceful
+@@ -465,6 +477,10 @@ static void sig_term(int sig)
+
+ static void sig_restart(int sig)
+ {
++ if (!retained_data) {
++ /* Main process (ap_pglobal) is dying */
++ return;
++ }
+ retained_data->mpm_state = AP_MPMQ_STOPPING;
+ if (retained_data->restart_pending
+ && (retained_data->is_ungraceful
+@@ -481,6 +497,10 @@ static void sig_restart(int sig)
+
+ static apr_status_t unset_signals(void *unused)
+ {
++ if (!retained_data) {
++ /* Main process (ap_pglobal) is dying */
++ return APR_SUCCESS;
++ }
+ retained_data->shutdown_pending = retained_data->restart_pending = 0;
+ retained_data->was_graceful = !retained_data->is_ungraceful;
+ retained_data->is_ungraceful = 0;
+@@ -494,6 +514,10 @@ AP_DECLARE(void) ap_unixd_mpm_set_signals(apr_pool_t *pconf, int one_process)
+ struct sigaction sa;
+ #endif
+
++ if (!one_process) {
++ ap_fatal_signal_setup(ap_server_conf, pconf);
++ }
++
+ /* Signals' handlers depend on retained data */
+ (void)ap_unixd_mpm_get_retained_data();
+
+diff --git a/server/main.c b/server/main.c
+index ba9d91c..edfbb0c 100644
+--- a/server/main.c
++++ b/server/main.c
+@@ -273,6 +273,30 @@ static int abort_on_oom(int retcode)
+ return retcode; /* unreachable, hopefully. */
+ }
+
++/* Deregister all hooks when clearing pconf (pre_cleanup).
++ * TODO: have a hook to deregister and run them from here?
++ * ap_clear_auth_internal() is already a candidate.
++ */
++static apr_status_t deregister_all_hooks(void *unused)
++{
++ (void)unused;
++ ap_clear_auth_internal();
++ apr_hook_deregister_all();
++ return APR_SUCCESS;
++}
++
++static void reset_process_pconf(process_rec *process)
++{
++ if (process->pconf) {
++ apr_pool_clear(process->pconf);
++ }
++ else {
++ apr_pool_create(&process->pconf, process->pool);
++ apr_pool_tag(process->pconf, "pconf");
++ }
++ apr_pool_pre_cleanup_register(process->pconf, NULL, deregister_all_hooks);
++}
++
+ static process_rec *init_process(int *argc, const char * const * *argv)
+ {
+ process_rec *process;
+@@ -317,8 +341,9 @@ static process_rec *init_process(int *argc, const char * const * *argv)
+ process = apr_palloc(cntx, sizeof(process_rec));
+ process->pool = cntx;
+
+- apr_pool_create(&process->pconf, process->pool);
+- apr_pool_tag(process->pconf, "pconf");
++ process->pconf = NULL;
++ reset_process_pconf(process);
++
+ process->argc = *argc;
+ process->argv = *argv;
+ process->short_name = apr_filepath_name_get((*argv)[0]);
+@@ -718,9 +743,7 @@ int main(int argc, const char * const argv[])
+
+ do {
+ ap_main_state = AP_SQ_MS_DESTROY_CONFIG;
+- apr_hook_deregister_all();
+- apr_pool_clear(pconf);
+- ap_clear_auth_internal();
++ reset_process_pconf(process);
+
+ ap_main_state = AP_SQ_MS_CREATE_CONFIG;
+ ap_config_generation++;
+diff --git a/server/mpm/event/event.c b/server/mpm/event/event.c
+index 6bbc8e5..312991e 100644
+--- a/server/mpm/event/event.c
++++ b/server/mpm/event/event.c
+@@ -2685,9 +2685,6 @@ static int event_run(apr_pool_t * _pconf, apr_pool_t * plog, server_rec * s)
+ ap_scoreboard_image->global->running_generation = retained->mpm->my_generation;
+ }
+
+- if (!one_process) {
+- ap_fatal_signal_setup(ap_server_conf, pconf);
+- }
+ ap_unixd_mpm_set_signals(pconf, one_process);
+
+ /* Don't thrash since num_buckets depends on the
+diff --git a/server/mpm/prefork/prefork.c b/server/mpm/prefork/prefork.c
+index 559f90a..619eace 100644
+--- a/server/mpm/prefork/prefork.c
++++ b/server/mpm/prefork/prefork.c
+@@ -853,9 +853,6 @@ static int prefork_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
+ ap_scoreboard_image->global->running_generation = retained->mpm->my_generation;
+ }
+
+- if (!one_process) {
+- ap_fatal_signal_setup(ap_server_conf, pconf);
+- }
+ ap_unixd_mpm_set_signals(pconf, one_process);
+
+ if (one_process) {
+diff --git a/server/mpm/worker/worker.c b/server/mpm/worker/worker.c
+index d2147bf..776ae7f 100644
+--- a/server/mpm/worker/worker.c
++++ b/server/mpm/worker/worker.c
+@@ -1671,9 +1671,6 @@ static int worker_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
+ ap_scoreboard_image->global->running_generation = retained->mpm->my_generation;
+ }
+
+- if (!one_process) {
+- ap_fatal_signal_setup(ap_server_conf, pconf);
+- }
+ ap_unixd_mpm_set_signals(pconf, one_process);
+
+ /* Don't thrash since num_buckets depends on the
+diff --git a/server/mpm_unix.c b/server/mpm_unix.c
+index 2f3d20e..1800f5d 100644
+--- a/server/mpm_unix.c
++++ b/server/mpm_unix.c
+@@ -1009,6 +1009,33 @@ AP_DECLARE(apr_status_t) ap_fatal_signal_child_setup(server_rec *s)
+ return APR_SUCCESS;
+ }
+
++/* We can't call sig_coredump (ap_log_error) once pconf is destroyed, so
++ * avoid double faults by restoring each default signal handler on cleanup.
++ */
++static apr_status_t fatal_signal_cleanup(void *unused)
++{
++ (void)unused;
++
++ apr_signal(SIGSEGV, SIG_DFL);
++#ifdef SIGBUS
++ apr_signal(SIGBUS, SIG_DFL);
++#endif /* SIGBUS */
++#ifdef SIGABORT
++ apr_signal(SIGABORT, SIG_DFL);
++#endif /* SIGABORT */
++#ifdef SIGABRT
++ apr_signal(SIGABRT, SIG_DFL);
++#endif /* SIGABRT */
++#ifdef SIGILL
++ apr_signal(SIGILL, SIG_DFL);
++#endif /* SIGILL */
++#ifdef SIGFPE
++ apr_signal(SIGFPE, SIG_DFL);
++#endif /* SIGFPE */
++
++ return APR_SUCCESS;
++}
++
+ AP_DECLARE(apr_status_t) ap_fatal_signal_setup(server_rec *s,
+ apr_pool_t *in_pconf)
+ {
+@@ -1071,6 +1098,8 @@ AP_DECLARE(apr_status_t) ap_fatal_signal_setup(server_rec *s,
+
+ pconf = in_pconf;
+ parent_pid = my_pid = getpid();
++ apr_pool_cleanup_register(pconf, NULL, fatal_signal_cleanup,
++ fatal_signal_cleanup);
+
+ return APR_SUCCESS;
+ }
diff --git a/debian/patches/series b/debian/patches/series
index 6e395fa..53273b5 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -10,3 +10,4 @@ reproducible_builds.diff
fix_logresolve_segfault.patch
mod_ssl_md-2.4.x-v5.diff
+0011-Signals-and-hooks-cleanup-on-exit-v3-2.4.x-for-bug-6.patch
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-apache/apache2.git
More information about the Pkg-apache-commits
mailing list