Welcome! Log In Create A New Profile

Advanced

[nginx] Fixed segfault when switching off master process during upgrade.

Sergey Kandaurov
November 25, 2022 06:48AM
details: https://hg.nginx.org/nginx/rev/8852f39311de
branches:
changeset: 8106:8852f39311de
user: Maxim Dounin <mdounin@mdounin.ru>
date: Wed Nov 23 23:48:53 2022 +0300
description:
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.

diffstat:

src/event/ngx_event.c | 4 +++-
src/os/unix/ngx_process_cycle.c | 10 ----------
2 files changed, 3 insertions(+), 11 deletions(-)

diffs (41 lines):

diff -r 09463dd9c504 -r 8852f39311de src/event/ngx_event.c
--- a/src/event/ngx_event.c Wed Nov 23 23:12:04 2022 +0300
+++ b/src/event/ngx_event.c Wed Nov 23 23:48:53 2022 +0300
@@ -813,7 +813,9 @@ ngx_event_process_init(ngx_cycle_t *cycl
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 -r 09463dd9c504 -r 8852f39311de src/os/unix/ngx_process_cycle.c
--- a/src/os/unix/ngx_process_cycle.c Wed Nov 23 23:12:04 2022 +0300
+++ b/src/os/unix/ngx_process_cycle.c Wed Nov 23 23:48:53 2022 +0300
@@ -759,7 +759,6 @@ ngx_worker_process_init(ngx_cycle_t *cyc
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 *cyc
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) {
_______________________________________________
nginx-devel mailing list -- nginx-devel@nginx.org
To unsubscribe send an email to nginx-devel-leave@nginx.org
Subject Author Views Posted

[nginx] Fixed segfault when switching off master process during upgrade.

Sergey Kandaurov 278 November 25, 2022 06:48AM



Sorry, you do not have permission to post/reply in this forum.

Online Users

Guests: 199
Record Number of Users: 6 on February 13, 2018
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready