Mercurial > hg > nginx
comparison src/core/nginx.c @ 6822:c045b4926b2c
Core: fixed environment on exit.
On exit environment allocated from a pool is no longer available, leading
to a segmentation fault if, for example, a library tries to use it from
an atexit() handler.
Fix is to allocate environment via ngx_alloc() instead, and explicitly
free it using a pool cleanup handler if it's no longer used (e.g., on
configuration reload).
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Wed, 07 Dec 2016 19:03:31 +0300 |
parents | 3b77efe05b92 |
children | 97c99bb43737 |
comparison
equal
deleted
inserted
replaced
6821:30b6f1ff192b | 6822:c045b4926b2c |
---|---|
10 #include <nginx.h> | 10 #include <nginx.h> |
11 | 11 |
12 | 12 |
13 static void ngx_show_version_info(void); | 13 static void ngx_show_version_info(void); |
14 static ngx_int_t ngx_add_inherited_sockets(ngx_cycle_t *cycle); | 14 static ngx_int_t ngx_add_inherited_sockets(ngx_cycle_t *cycle); |
15 static void ngx_cleanup_environment(void *data); | |
15 static ngx_int_t ngx_get_options(int argc, char *const *argv); | 16 static ngx_int_t ngx_get_options(int argc, char *const *argv); |
16 static ngx_int_t ngx_process_options(ngx_cycle_t *cycle); | 17 static ngx_int_t ngx_process_options(ngx_cycle_t *cycle); |
17 static ngx_int_t ngx_save_argv(ngx_cycle_t *cycle, int argc, char *const *argv); | 18 static ngx_int_t ngx_save_argv(ngx_cycle_t *cycle, int argc, char *const *argv); |
18 static void *ngx_core_module_create_conf(ngx_cycle_t *cycle); | 19 static void *ngx_core_module_create_conf(ngx_cycle_t *cycle); |
19 static char *ngx_core_module_init_conf(ngx_cycle_t *cycle, void *conf); | 20 static char *ngx_core_module_init_conf(ngx_cycle_t *cycle, void *conf); |
493 | 494 |
494 | 495 |
495 char ** | 496 char ** |
496 ngx_set_environment(ngx_cycle_t *cycle, ngx_uint_t *last) | 497 ngx_set_environment(ngx_cycle_t *cycle, ngx_uint_t *last) |
497 { | 498 { |
498 char **p, **env; | 499 char **p, **env; |
499 ngx_str_t *var; | 500 ngx_str_t *var; |
500 ngx_uint_t i, n; | 501 ngx_uint_t i, n; |
501 ngx_core_conf_t *ccf; | 502 ngx_core_conf_t *ccf; |
503 ngx_pool_cleanup_t *cln; | |
502 | 504 |
503 ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); | 505 ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); |
504 | 506 |
505 if (last == NULL && ccf->environment) { | 507 if (last == NULL && ccf->environment) { |
506 return ccf->environment; | 508 return ccf->environment; |
548 } | 550 } |
549 } | 551 } |
550 | 552 |
551 if (last) { | 553 if (last) { |
552 env = ngx_alloc((*last + n + 1) * sizeof(char *), cycle->log); | 554 env = ngx_alloc((*last + n + 1) * sizeof(char *), cycle->log); |
555 if (env == NULL) { | |
556 return NULL; | |
557 } | |
558 | |
553 *last = n; | 559 *last = n; |
554 | 560 |
555 } else { | 561 } else { |
556 env = ngx_palloc(cycle->pool, (n + 1) * sizeof(char *)); | 562 cln = ngx_pool_cleanup_add(cycle->pool, 0); |
557 } | 563 if (cln == NULL) { |
558 | 564 return NULL; |
559 if (env == NULL) { | 565 } |
560 return NULL; | 566 |
567 env = ngx_alloc((n + 1) * sizeof(char *), cycle->log); | |
568 if (env == NULL) { | |
569 return NULL; | |
570 } | |
571 | |
572 cln->handler = ngx_cleanup_environment; | |
573 cln->data = env; | |
561 } | 574 } |
562 | 575 |
563 n = 0; | 576 n = 0; |
564 | 577 |
565 for (i = 0; i < ccf->env.nelts; i++) { | 578 for (i = 0; i < ccf->env.nelts; i++) { |
586 ccf->environment = env; | 599 ccf->environment = env; |
587 environ = env; | 600 environ = env; |
588 } | 601 } |
589 | 602 |
590 return env; | 603 return env; |
604 } | |
605 | |
606 | |
607 static void | |
608 ngx_cleanup_environment(void *data) | |
609 { | |
610 char **env = data; | |
611 | |
612 if (environ == env) { | |
613 | |
614 /* | |
615 * if the environment is still used, as it happens on exit, | |
616 * the only option is to leak it | |
617 */ | |
618 | |
619 return; | |
620 } | |
621 | |
622 ngx_free(env); | |
591 } | 623 } |
592 | 624 |
593 | 625 |
594 ngx_pid_t | 626 ngx_pid_t |
595 ngx_exec_new_binary(ngx_cycle_t *cycle, char *const *argv) | 627 ngx_exec_new_binary(ngx_cycle_t *cycle, char *const *argv) |