]> git.kaiwu.me - nginx.git/commitdiff
Fixed segfault when switching off master process during upgrade.
authorMaxim Dounin <mdounin@mdounin.ru>
Wed, 23 Nov 2022 20:48:53 +0000 (23:48 +0300)
committerMaxim Dounin <mdounin@mdounin.ru>
Wed, 23 Nov 2022 20:48:53 +0000 (23:48 +0300)
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.

src/event/ngx_event.c
src/os/unix/ngx_process_cycle.c

index 77b07f6e16f792bfb4a53080b4ed2b3e12fed4cf..d81547af4db0c73c703b5505bbbead8d0fb52414 100644 (file)
@@ -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) {
 
                 /*
index 821539bb717b845d17495b690095dda123086e67..98d2dd29b1498f2e014dcac0b014c39f023fca4d 100644 (file)
@@ -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) {