From 1c79973b425e1c44a99a009e6a32f248261b685c Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Fri, 23 Oct 2020 11:52:25 +0200 Subject: backport fix for https://bugs.php.net/74083 from 7.4 master PHP-fpm is stopped on multiple reloads --- php-7.3.24-fpm.patch | 219 +++++++++++++++++++++++++++++++++++++++++++++++++++ php.spec | 10 ++- 2 files changed, 228 insertions(+), 1 deletion(-) create mode 100644 php-7.3.24-fpm.patch diff --git a/php-7.3.24-fpm.patch b/php-7.3.24-fpm.patch new file mode 100644 index 0000000..1165970 --- /dev/null +++ b/php-7.3.24-fpm.patch @@ -0,0 +1,219 @@ +Fix for https://bugs.php.net/74083 master PHP-fpm is stopped on multiple reloads +backported for 7.4 from + +From ae5154c6c6af7ba7c592f8af006b7cadd0d66d6e Mon Sep 17 00:00:00 2001 +From: Maksim Nikulin +Date: Wed, 24 Jul 2019 16:50:57 +0700 +Subject: [PATCH] Block signals during fpm master initialization + +From e37bd5dcc2e8f269c6031d86429311c8cf243060 Mon Sep 17 00:00:00 2001 +From: Maksim Nikulin +Date: Mon, 21 Oct 2019 14:23:29 +0700 +Subject: [PATCH] Do not let PHP-FPM children miss SIGTERM, SIGQUIT + + +diff -up ./sapi/fpm/fpm/fpm_children.c.fpmsig ./sapi/fpm/fpm/fpm_children.c +--- ./sapi/fpm/fpm/fpm_children.c.fpmsig 2020-10-23 10:36:31.423925856 +0200 ++++ ./sapi/fpm/fpm/fpm_children.c 2020-10-23 10:36:38.872900642 +0200 +@@ -404,6 +404,11 @@ int fpm_children_make(struct fpm_worker_ + return 2; + } + ++ zlog(ZLOG_DEBUG, "blocking signals before child birth"); ++ if (0 > fpm_signals_child_block()) { ++ zlog(ZLOG_WARNING, "child may miss signals"); ++ } ++ + pid = fork(); + + switch (pid) { +@@ -415,12 +420,16 @@ int fpm_children_make(struct fpm_worker_ + return 0; + + case -1 : ++ zlog(ZLOG_DEBUG, "unblocking signals"); ++ fpm_signals_unblock(); + zlog(ZLOG_SYSERROR, "fork() failed"); + + fpm_resources_discard(child); + return 2; + + default : ++ zlog(ZLOG_DEBUG, "unblocking signals, child born"); ++ fpm_signals_unblock(); + child->pid = pid; + fpm_clock_get(&child->started); + fpm_parent_resources_use(child); +diff -up ./sapi/fpm/fpm/fpm_main.c.fpmsig ./sapi/fpm/fpm/fpm_main.c +--- ./sapi/fpm/fpm/fpm_main.c.fpmsig 2020-10-13 11:27:02.000000000 +0200 ++++ ./sapi/fpm/fpm/fpm_main.c 2020-10-23 10:36:38.873900639 +0200 +@@ -90,6 +90,7 @@ int __riscosify_control = __RISCOSIFY_ST + #include "fpm.h" + #include "fpm_request.h" + #include "fpm_status.h" ++#include "fpm_signals.h" + #include "fpm_conf.h" + #include "fpm_php.h" + #include "fpm_log.h" +@@ -1584,6 +1585,11 @@ int main(int argc, char *argv[]) + closes it. in apache|apxs mode apache + does that for us! thies@thieso.net + 20000419 */ ++ ++ if (0 > fpm_signals_init_mask() || 0 > fpm_signals_block()) { ++ zlog(ZLOG_WARNING, "Could die in the case of too early reload signal"); ++ } ++ zlog(ZLOG_DEBUG, "Blocked some signals"); + #endif + #endif + +diff -up ./sapi/fpm/fpm/fpm_process_ctl.c.fpmsig ./sapi/fpm/fpm/fpm_process_ctl.c +--- ./sapi/fpm/fpm/fpm_process_ctl.c.fpmsig 2020-10-13 11:27:02.000000000 +0200 ++++ ./sapi/fpm/fpm/fpm_process_ctl.c 2020-10-23 10:36:11.921991864 +0200 +@@ -77,6 +77,10 @@ static void fpm_pctl_exit() /* {{{ */ + + static void fpm_pctl_exec() /* {{{ */ + { ++ zlog(ZLOG_DEBUG, "Blocking some signals before reexec"); ++ if (0 > fpm_signals_block()) { ++ zlog(ZLOG_WARNING, "concurrent reloads may be unstable"); ++ } + + zlog(ZLOG_NOTICE, "reloading: execvp(\"%s\", {\"%s\"" + "%s%s%s" "%s%s%s" "%s%s%s" "%s%s%s" "%s%s%s" +diff -up ./sapi/fpm/fpm/fpm_signals.c.fpmsig ./sapi/fpm/fpm/fpm_signals.c +--- ./sapi/fpm/fpm/fpm_signals.c.fpmsig 2020-10-13 11:27:02.000000000 +0200 ++++ ./sapi/fpm/fpm/fpm_signals.c 2020-10-23 10:36:38.873900639 +0200 +@@ -19,6 +19,8 @@ + #include "zlog.h" + + static int sp[2]; ++static sigset_t block_sigset; ++static sigset_t child_block_sigset; + + const char *fpm_signal_names[NSIG + 1] = { + #ifdef SIGHUP +@@ -165,8 +167,11 @@ static void sig_handler(int signo) /* {{ + int saved_errno; + + if (fpm_globals.parent_pid != getpid()) { +- /* prevent a signal race condition when child process +- have not set up it's own signal handler yet */ ++ /* Avoid using of signal handlers from the master process in a worker ++ before the child sets up its own signal handlers. ++ Normally it is prevented by the sigprocmask() calls ++ around fork(). This execution branch is a last resort trap ++ that has no protection against #76601. */ + return; + } + +@@ -210,6 +215,11 @@ int fpm_signals_init_main() /* {{{ */ + zlog(ZLOG_SYSERROR, "failed to init signals: sigaction()"); + return -1; + } ++ ++ zlog(ZLOG_DEBUG, "Unblocking all signals"); ++ if (0 > fpm_signals_unblock()) { ++ return -1; ++ } + return 0; + } + /* }}} */ +@@ -241,6 +251,10 @@ int fpm_signals_init_child() /* {{{ */ + } + + zend_signal_init(); ++ ++ if (0 > fpm_signals_unblock()) { ++ return -1; ++ } + return 0; + } + /* }}} */ +@@ -250,3 +264,72 @@ int fpm_signals_get_fd() /* {{{ */ + return sp[0]; + } + /* }}} */ ++ ++int fpm_signals_init_mask() /* {{{ */ ++{ ++ /* Subset of signals from fpm_signals_init_main() and fpm_got_signal() ++ blocked to avoid unexpected death during early init ++ or during reload just after execvp() or fork */ ++ int init_signal_array[] = { SIGUSR1, SIGUSR2, SIGCHLD }; ++ size_t size = sizeof(init_signal_array)/sizeof(init_signal_array[0]); ++ size_t i = 0; ++ if (0 > sigemptyset(&block_sigset) || ++ 0 > sigemptyset(&child_block_sigset)) { ++ zlog(ZLOG_SYSERROR, "failed to prepare signal block mask: sigemptyset()"); ++ return -1; ++ } ++ for (i = 0; i < size; ++i) { ++ int sig_i = init_signal_array[i]; ++ if (0 > sigaddset(&block_sigset, sig_i) || ++ 0 > sigaddset(&child_block_sigset, sig_i)) { ++ if (sig_i <= NSIG && fpm_signal_names[sig_i] != NULL) { ++ zlog(ZLOG_SYSERROR, "failed to prepare signal block mask: sigaddset(%s)", ++ fpm_signal_names[sig_i]); ++ } else { ++ zlog(ZLOG_SYSERROR, "failed to prepare signal block mask: sigaddset(%d)", sig_i); ++ } ++ return -1; ++ } ++ } ++ if (0 > sigaddset(&child_block_sigset, SIGTERM) || ++ 0 > sigaddset(&child_block_sigset, SIGQUIT)) { ++ zlog(ZLOG_SYSERROR, "failed to prepare child signal block mask: sigaddset()"); ++ return -1; ++ } ++ return 0; ++} ++/* }}} */ ++ ++int fpm_signals_block() /* {{{ */ ++{ ++ if (0 > sigprocmask(SIG_BLOCK, &block_sigset, NULL)) { ++ zlog(ZLOG_SYSERROR, "failed to block signals"); ++ return -1; ++ } ++ return 0; ++} ++/* }}} */ ++ ++int fpm_signals_child_block() /* {{{ */ ++{ ++ if (0 > sigprocmask(SIG_BLOCK, &child_block_sigset, NULL)) { ++ zlog(ZLOG_SYSERROR, "failed to block child signals"); ++ return -1; ++ } ++ return 0; ++} ++/* }}} */ ++ ++int fpm_signals_unblock() /* {{{ */ ++{ ++ /* Ensure that during reload after upgrade all signals are unblocked. ++ block_sigset could have different value before execve() */ ++ sigset_t all_signals; ++ sigfillset(&all_signals); ++ if (0 > sigprocmask(SIG_UNBLOCK, &all_signals, NULL)) { ++ zlog(ZLOG_SYSERROR, "failed to unblock signals"); ++ return -1; ++ } ++ return 0; ++} ++/* }}} */ +diff -up ./sapi/fpm/fpm/fpm_signals.h.fpmsig ./sapi/fpm/fpm/fpm_signals.h +--- ./sapi/fpm/fpm/fpm_signals.h.fpmsig 2020-10-13 11:27:02.000000000 +0200 ++++ ./sapi/fpm/fpm/fpm_signals.h 2020-10-23 10:36:38.873900639 +0200 +@@ -8,6 +8,10 @@ + int fpm_signals_init_main(); + int fpm_signals_init_child(); + int fpm_signals_get_fd(); ++int fpm_signals_init_mask(); ++int fpm_signals_block(); ++int fpm_signals_child_block(); ++int fpm_signals_unblock(); + + extern const char *fpm_signal_names[NSIG + 1]; + diff --git a/php.spec b/php.spec index cff8211..521047f 100644 --- a/php.spec +++ b/php.spec @@ -141,7 +141,7 @@ Summary: PHP scripting language for creating dynamic web sites Name: %{?scl_prefix}php Version: %{upver}%{?rcver:~%{rcver}} -Release: 1%{?dist} +Release: 2%{?dist} # All files licensed under PHP version 3.01, except # Zend is licensed under Zend # TSRM is licensed under BSD @@ -195,6 +195,9 @@ Patch46: php-7.3.20-fixheader.patch Patch47: php-7.3.20-phpinfo.patch # backport PDOStatement::getColumnMeta from 7.4 Patch48: php-7.3.3-pdooci.patch +# backport FPM signals changes from 7.4 +# https://bugs.php.net/74083 master PHP-fpm is stopped on multiple reloads +Patch49: php-7.3.24-fpm.patch # RC Patch Patch91: php-7.2.0-oci8conf.patch @@ -962,6 +965,7 @@ sed -e 's/php-devel/%{?scl_prefix}php-devel/' -i scripts/phpize.in %patch46 -p1 -b .fixheader %patch47 -p1 -b .phpinfo %patch48 -p1 -b .pdooci +%patch49 -p1 -b .fpmsig %patch91 -p1 -b .remi-oci8 @@ -1919,6 +1923,10 @@ fi %changelog +* Fri Oct 23 2020 Remi Collet - 7.3.24~RC1-2 +- backport fix for https://bugs.php.net/74083 from 7.4 + master PHP-fpm is stopped on multiple reloads + * Tue Oct 13 2020 Remi Collet - 7.3.24~RC1-1 - update to 7.3.24RC1 -- cgit