# HG changeset patch # User Maxim Dounin # Date 1508259136 -10800 # Node ID 9ef704d8563af4aff6817ab1c694fb40591f20b3 # Parent d87f29d764ce5378ec68118017670be75bad736d Core: free shared memory zones only after reconfiguration. This is what usually happens for zones no longer used in the new configuration, but zones where size or tag were changed were freed when creating new memory zones. If reconfiguration failed (for example, due to a conflicting listening socket), this resulted in a segmentation fault in the master process. Reported by Zhihua Cao, http://mailman.nginx.org/pipermail/nginx-devel/2017-October/010536.html. diff --git a/src/core/ngx_cycle.c b/src/core/ngx_cycle.c --- a/src/core/ngx_cycle.c +++ b/src/core/ngx_cycle.c @@ -470,8 +470,6 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) goto shm_zone_found; } - ngx_shm_free(&oshm_zone[n].shm); - break; } @@ -662,14 +660,26 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) n = 0; } - if (oshm_zone[i].shm.name.len == shm_zone[n].shm.name.len - && ngx_strncmp(oshm_zone[i].shm.name.data, - shm_zone[n].shm.name.data, - oshm_zone[i].shm.name.len) - == 0) + if (oshm_zone[i].shm.name.len != shm_zone[n].shm.name.len) { + continue; + } + + if (ngx_strncmp(oshm_zone[i].shm.name.data, + shm_zone[n].shm.name.data, + oshm_zone[i].shm.name.len) + != 0) + { + continue; + } + + if (oshm_zone[i].tag == shm_zone[n].tag + && oshm_zone[i].shm.size == shm_zone[n].shm.size + && !oshm_zone[i].noreuse) { goto live_shm_zone; } + + break; } ngx_shm_free(&oshm_zone[i].shm);