summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacob Hipps <jacob@ycnrg.org>2018-02-23 11:36:59 -0500
committerJakub Zelenka <bukka@php.net>2018-03-30 17:20:19 +0100
commit77bf9245d22a2a15f0e1654e69c8885ac723dc74 (patch)
treef913ac670108abc4b6bcc2279a6ab7f95a3becf0
parent8b104d789317d96f6d3e23e635f0ca288c0a23ee (diff)
downloadphp-git-77bf9245d22a2a15f0e1654e69c8885ac723dc74.tar.gz
Fix bug #68440: [sapi/fpm] use multiple FPM_SOCKETS env vars to prevent hitting MAX_ARG_STRLEN with a large number of pools
-rw-r--r--sapi/fpm/fpm/fpm_sockets.c74
-rw-r--r--sapi/fpm/fpm/fpm_sockets.h5
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);