comparison src/core/nginx.c @ 9134:c209dc4eed17

Core: fixed environment variables on exit. Similarly to 6822:c045b4926b2c, environment variables introduced with the "env" directive (and "NGINX_BPF_MAPS" added by QUIC) are now allocated via ngx_alloc(), and explicitly freed by a cleanup handler if no longer used. In collaboration with Sergey Kandaurov.
author Maxim Dounin <mdounin@mdounin.ru>
date Wed, 19 Jul 2023 05:09:23 +0300
parents 7df607cb2d11
children 6a3ee145d0b5
comparison
equal deleted inserted replaced
9133:f91dc350be9f 9134:c209dc4eed17
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 void ngx_cleanup_environment(void *data);
16 static void ngx_cleanup_environment_variable(void *data);
16 static ngx_int_t ngx_get_options(int argc, char *const *argv); 17 static ngx_int_t ngx_get_options(int argc, char *const *argv);
17 static ngx_int_t ngx_process_options(ngx_cycle_t *cycle); 18 static ngx_int_t ngx_process_options(ngx_cycle_t *cycle);
18 static ngx_int_t ngx_save_argv(ngx_cycle_t *cycle, int argc, char *const *argv); 19 static ngx_int_t ngx_save_argv(ngx_cycle_t *cycle, int argc, char *const *argv);
19 static void *ngx_core_module_create_conf(ngx_cycle_t *cycle); 20 static void *ngx_core_module_create_conf(ngx_cycle_t *cycle);
20 static char *ngx_core_module_init_conf(ngx_cycle_t *cycle, void *conf); 21 static char *ngx_core_module_init_conf(ngx_cycle_t *cycle, void *conf);
516 517
517 518
518 char ** 519 char **
519 ngx_set_environment(ngx_cycle_t *cycle, ngx_uint_t *last) 520 ngx_set_environment(ngx_cycle_t *cycle, ngx_uint_t *last)
520 { 521 {
521 char **p, **env; 522 char **p, **env, *str;
523 size_t len;
522 ngx_str_t *var; 524 ngx_str_t *var;
523 ngx_uint_t i, n; 525 ngx_uint_t i, n;
524 ngx_core_conf_t *ccf; 526 ngx_core_conf_t *ccf;
525 ngx_pool_cleanup_t *cln; 527 ngx_pool_cleanup_t *cln;
526 528
598 n = 0; 600 n = 0;
599 601
600 for (i = 0; i < ccf->env.nelts; i++) { 602 for (i = 0; i < ccf->env.nelts; i++) {
601 603
602 if (var[i].data[var[i].len] == '=') { 604 if (var[i].data[var[i].len] == '=') {
603 env[n++] = (char *) var[i].data; 605
606 if (last) {
607 env[n++] = (char *) var[i].data;
608 continue;
609 }
610
611 cln = ngx_pool_cleanup_add(cycle->pool, 0);
612 if (cln == NULL) {
613 return NULL;
614 }
615
616 len = ngx_strlen(var[i].data) + 1;
617
618 str = ngx_alloc(len, cycle->log);
619 if (str == NULL) {
620 return NULL;
621 }
622
623 ngx_memcpy(str, var[i].data, len);
624
625 cln->handler = ngx_cleanup_environment_variable;
626 cln->data = str;
627
628 env[n++] = str;
629
604 continue; 630 continue;
605 } 631 }
606 632
607 for (p = ngx_os_environ; *p; p++) { 633 for (p = ngx_os_environ; *p; p++) {
608 634
640 666
641 return; 667 return;
642 } 668 }
643 669
644 ngx_free(env); 670 ngx_free(env);
671 }
672
673
674 static void
675 ngx_cleanup_environment_variable(void *data)
676 {
677 char *var = data;
678
679 char **p;
680
681 for (p = environ; *p; p++) {
682
683 /*
684 * if an environment variable is still used, as it happens on exit,
685 * the only option is to leak it
686 */
687
688 if (*p == var) {
689 return;
690 }
691 }
692
693 ngx_free(var);
645 } 694 }
646 695
647 696
648 ngx_pid_t 697 ngx_pid_t
649 ngx_exec_new_binary(ngx_cycle_t *cycle, char *const *argv) 698 ngx_exec_new_binary(ngx_cycle_t *cycle, char *const *argv)