From 77bf9245d22a2a15f0e1654e69c8885ac723dc74 Mon Sep 17 00:00:00 2001 From: Jacob Hipps Date: Fri, 23 Feb 2018 11:36:59 -0500 Subject: [PATCH] Fix bug #68440: [sapi/fpm] use multiple FPM_SOCKETS env vars to prevent hitting MAX_ARG_STRLEN with a large number of pools --- sapi/fpm/fpm/fpm_sockets.c | 74 +++++++++++++++++++++++++------------- sapi/fpm/fpm/fpm_sockets.h | 5 ++- 2 files changed, 54 insertions(+), 25 deletions(-) diff --git a/sapi/fpm/fpm/fpm_sockets.c b/sapi/fpm/fpm/fpm_sockets.c index f27bb4afe3..dc7a8abd72 100644 --- a/sapi/fpm/fpm/fpm_sockets.c +++ b/sapi/fpm/fpm/fpm_sockets.c @@ -44,6 +44,10 @@ enum { FPM_GET_USE_SOCKET = 1, FPM_STORE_SOCKET = 2, FPM_STORE_USE_SOCKET = 3 }; static void fpm_sockets_cleanup(int which, void *arg) /* {{{ */ { unsigned i; + unsigned socket_set_count = 0; + unsigned socket_set[FPM_ENV_SOCKET_SET_MAX]; + unsigned socket_set_buf = 0; + char envname[16]; char *env_value = 0; int p = 0; struct listening_socket_s *ls = sockets_list.data; @@ -54,8 +58,20 @@ static void fpm_sockets_cleanup(int which, void *arg) /* {{{ */ } else { /* on PARENT EXEC we want socket fds to be inherited through environment variable */ char fd[32]; sprintf(fd, "%d", ls->sock); - env_value = realloc(env_value, p + (p ? 1 : 0) + strlen(ls->key) + 1 + strlen(fd) + 1); - p += sprintf(env_value + p, "%s%s=%s", p ? "," : "", ls->key, fd); + + socket_set_buf = (i % FPM_ENV_SOCKET_SET_SIZE == 0 && i) ? 1 : 0; + env_value = realloc(env_value, p + (p ? 1 : 0) + strlen(ls->key) + 1 + strlen(fd) + socket_set_buf + 1); + + if (i % FPM_ENV_SOCKET_SET_SIZE == 0) { + socket_set[socket_set_count] = p + socket_set_buf; + socket_set_count++; + if (i) { + *(env_value + p + 1) = 0; + } + } + + p += sprintf(env_value + p + socket_set_buf, "%s%s=%s", (p && !socket_set_buf) ? "," : "", ls->key, fd); + p += socket_set_buf; } if (which == FPM_CLEANUP_PARENT_EXIT_MAIN) { @@ -67,7 +83,10 @@ static void fpm_sockets_cleanup(int which, void *arg) /* {{{ */ } if (env_value) { - setenv("FPM_SOCKETS", env_value, 1); + for(i = 0; i < socket_set_count; i++) { + sprintf(envname, "FPM_SOCKETS_%d", i); + setenv(envname, env_value + socket_set[i], 1); + } free(env_value); } @@ -324,7 +343,8 @@ int fpm_sockets_init_main() /* {{{ */ { unsigned i, lq_len; struct fpm_worker_pool_s *wp; - char *inherited = getenv("FPM_SOCKETS"); + char sockname[16]; + char *inherited; struct listening_socket_s *ls; if (0 == fpm_array_init(&sockets_list, sizeof(struct listening_socket_s), 10)) { @@ -332,28 +352,34 @@ int fpm_sockets_init_main() /* {{{ */ } /* import inherited sockets */ - while (inherited && *inherited) { - char *comma = strchr(inherited, ','); - int type, fd_no; - char *eq; - - if (comma) { - *comma = '\0'; - } + for (i = 0; i < FPM_ENV_SOCKET_SET_MAX; i++) { + sprintf(sockname, "FPM_SOCKETS_%d", i); + inherited = getenv(sockname); + if (!inherited) break; + + while (inherited && *inherited) { + char *comma = strchr(inherited, ','); + int type, fd_no; + char *eq; + + if (comma) { + *comma = '\0'; + } - eq = strchr(inherited, '='); - if (eq) { - *eq = '\0'; - fd_no = atoi(eq + 1); - type = fpm_sockets_domain_from_address(inherited); - zlog(ZLOG_NOTICE, "using inherited socket fd=%d, \"%s\"", fd_no, inherited); - fpm_sockets_hash_op(fd_no, 0, inherited, type, FPM_STORE_SOCKET); - } + eq = strchr(inherited, '='); + if (eq) { + *eq = '\0'; + fd_no = atoi(eq + 1); + type = fpm_sockets_domain_from_address(inherited); + zlog(ZLOG_NOTICE, "using inherited socket fd=%d, \"%s\"", fd_no, inherited); + fpm_sockets_hash_op(fd_no, 0, inherited, type, FPM_STORE_SOCKET); + } - if (comma) { - inherited = comma + 1; - } else { - inherited = 0; + if (comma) { + inherited = comma + 1; + } else { + inherited = 0; + } } } diff --git a/sapi/fpm/fpm/fpm_sockets.h b/sapi/fpm/fpm/fpm_sockets.h index 2bd3d58249..98b40ff206 100644 --- a/sapi/fpm/fpm/fpm_sockets.h +++ b/sapi/fpm/fpm/fpm_sockets.h @@ -19,9 +19,12 @@ #if (__FreeBSD__) || (__OpenBSD__) #define FPM_BACKLOG_DEFAULT -1 #else -#define FPM_BACKLOG_DEFAULT 511 +#define FPM_BACKLOG_DEFAULT 511 #endif +#define FPM_ENV_SOCKET_SET_MAX 256 +#define FPM_ENV_SOCKET_SET_SIZE 128 + enum fpm_address_domain fpm_sockets_domain_from_address(char *addr); int fpm_sockets_init_main(); int fpm_socket_get_listening_queue(int sock, unsigned *cur_lq, unsigned *max_lq); -- 2.40.0