summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxim Dounin <mdounin@mdounin.ru>2022-11-23 23:48:53 +0300
committerMaxim Dounin <mdounin@mdounin.ru>2022-11-23 23:48:53 +0300
commitd52e5684437aedd6bb74d6b2b602b7306f4212ba (patch)
tree36652257f10b3d84604b33bd30b49c4d6064991f
parent593bb543873ac57efade09dbcc2f93ab6b4d5ab0 (diff)
downloadnginx-d52e5684437aedd6bb74d6b2b602b7306f4212ba.tar.gz
Fixed segfault when switching off master process during upgrade.
Binary upgrades are not supported without master process, but it is, however, possible, that nginx running with master process is asked to upgrade binary, and the configuration file as available on disk at this time includes "master_process off;". If this happens, listening sockets inherited from the previous binary will have ls[i].previous set. But the old cycle on initial process startup, including startup after binary upgrade, is destroyed by ngx_init_cycle() once configuration parsing is complete. As a result, an attempt to dereference ls[i].previous in ngx_event_process_init() accesses already freed memory. Fix is to avoid looking into ls[i].previous if the old cycle is already freed. With this change it is also no longer needed to clear ls[i].previous in worker processes, so the relevant code was removed.
-rw-r--r--src/event/ngx_event.c4
-rw-r--r--src/os/unix/ngx_process_cycle.c10
2 files changed, 3 insertions, 11 deletions
diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c
index 77b07f6e1..d81547af4 100644
--- a/src/event/ngx_event.c
+++ b/src/event/ngx_event.c
@@ -813,7 +813,9 @@ ngx_event_process_init(ngx_cycle_t *cycle)
rev->deferred_accept = ls[i].deferred_accept;
#endif
- if (!(ngx_event_flags & NGX_USE_IOCP_EVENT)) {
+ if (!(ngx_event_flags & NGX_USE_IOCP_EVENT)
+ && cycle->old_cycle)
+ {
if (ls[i].previous) {
/*
diff --git a/src/os/unix/ngx_process_cycle.c b/src/os/unix/ngx_process_cycle.c
index 821539bb7..98d2dd29b 100644
--- a/src/os/unix/ngx_process_cycle.c
+++ b/src/os/unix/ngx_process_cycle.c
@@ -759,7 +759,6 @@ ngx_worker_process_init(ngx_cycle_t *cycle, ngx_int_t worker)
ngx_cpuset_t *cpu_affinity;
struct rlimit rlmt;
ngx_core_conf_t *ccf;
- ngx_listening_t *ls;
if (ngx_set_environment(cycle, NULL) == NULL) {
/* fatal */
@@ -889,15 +888,6 @@ ngx_worker_process_init(ngx_cycle_t *cycle, ngx_int_t worker)
tp = ngx_timeofday();
srandom(((unsigned) ngx_pid << 16) ^ tp->sec ^ tp->msec);
- /*
- * disable deleting previous events for the listening sockets because
- * in the worker processes there are no events at all at this point
- */
- ls = cycle->listening.elts;
- for (i = 0; i < cycle->listening.nelts; i++) {
- ls[i].previous = NULL;
- }
-
for (i = 0; cycle->modules[i]; i++) {
if (cycle->modules[i]->init_process) {
if (cycle->modules[i]->init_process(cycle) == NGX_ERROR) {