From d7483bf1af704c1ef55e706ed3e44a09ee1e1f9b Mon Sep 17 00:00:00 2001 From: Roman Arutyunyan Date: Thu, 3 Nov 2022 15:52:55 +0400 Subject: [PATCH 01/17] Version bump. --- src/core/nginx.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/nginx.h b/src/core/nginx.h index a7571cdf3..f4e9d7c91 100644 --- a/src/core/nginx.h +++ b/src/core/nginx.h @@ -9,8 +9,8 @@ #define _NGINX_H_INCLUDED_ -#define nginx_version 1023002 -#define NGINX_VERSION "1.23.2" +#define nginx_version 1023003 +#define NGINX_VERSION "1.23.3" #define NGINX_VER "nginx/" NGINX_VERSION #ifdef NGX_BUILD From 7600ca028644d3ecc7e62499d71bbe21fe3bda0d Mon Sep 17 00:00:00 2001 From: Roman Arutyunyan Date: Wed, 2 Nov 2022 13:46:16 +0400 Subject: [PATCH 02/17] Increased maximum read PROXY protocol header size. Maximum size for reading the PROXY protocol header is increased to 4096 to accommodate a bigger number of TLVs, which are supported since cca4c8a715de. Maximum size for writing the PROXY protocol header is not changed since only version 1 is currently supported. --- src/core/ngx_proxy_protocol.c | 2 +- src/core/ngx_proxy_protocol.h | 3 ++- src/mail/ngx_mail_proxy_module.c | 4 ++-- src/stream/ngx_stream_proxy_module.c | 10 ++++++---- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/core/ngx_proxy_protocol.c b/src/core/ngx_proxy_protocol.c index 2d9c095b1..212763647 100644 --- a/src/core/ngx_proxy_protocol.c +++ b/src/core/ngx_proxy_protocol.c @@ -281,7 +281,7 @@ ngx_proxy_protocol_write(ngx_connection_t *c, u_char *buf, u_char *last) { ngx_uint_t port, lport; - if (last - buf < NGX_PROXY_PROTOCOL_MAX_HEADER) { + if (last - buf < NGX_PROXY_PROTOCOL_V1_MAX_HEADER) { return NULL; } diff --git a/src/core/ngx_proxy_protocol.h b/src/core/ngx_proxy_protocol.h index 7d9d3eb70..d1749f57b 100644 --- a/src/core/ngx_proxy_protocol.h +++ b/src/core/ngx_proxy_protocol.h @@ -13,7 +13,8 @@ #include -#define NGX_PROXY_PROTOCOL_MAX_HEADER 107 +#define NGX_PROXY_PROTOCOL_V1_MAX_HEADER 107 +#define NGX_PROXY_PROTOCOL_MAX_HEADER 4096 struct ngx_proxy_protocol_s { diff --git a/src/mail/ngx_mail_proxy_module.c b/src/mail/ngx_mail_proxy_module.c index a7ab0776e..06679d4e0 100644 --- a/src/mail/ngx_mail_proxy_module.c +++ b/src/mail/ngx_mail_proxy_module.c @@ -890,7 +890,7 @@ ngx_mail_proxy_send_proxy_protocol(ngx_mail_session_t *s) u_char *p; ssize_t n, size; ngx_connection_t *c; - u_char buf[NGX_PROXY_PROTOCOL_MAX_HEADER]; + u_char buf[NGX_PROXY_PROTOCOL_V1_MAX_HEADER]; s->connection->log->action = "sending PROXY protocol header to upstream"; @@ -898,7 +898,7 @@ ngx_mail_proxy_send_proxy_protocol(ngx_mail_session_t *s) "mail proxy send PROXY protocol header"); p = ngx_proxy_protocol_write(s->connection, buf, - buf + NGX_PROXY_PROTOCOL_MAX_HEADER); + buf + NGX_PROXY_PROTOCOL_V1_MAX_HEADER); if (p == NULL) { ngx_mail_proxy_internal_server_error(s); return NGX_ERROR; diff --git a/src/stream/ngx_stream_proxy_module.c b/src/stream/ngx_stream_proxy_module.c index 6b0d43ea4..e13d72f3a 100644 --- a/src/stream/ngx_stream_proxy_module.c +++ b/src/stream/ngx_stream_proxy_module.c @@ -894,7 +894,7 @@ ngx_stream_proxy_init_upstream(ngx_stream_session_t *s) return; } - p = ngx_pnalloc(c->pool, NGX_PROXY_PROTOCOL_MAX_HEADER); + p = ngx_pnalloc(c->pool, NGX_PROXY_PROTOCOL_V1_MAX_HEADER); if (p == NULL) { ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR); return; @@ -902,7 +902,8 @@ ngx_stream_proxy_init_upstream(ngx_stream_session_t *s) cl->buf->pos = p; - p = ngx_proxy_protocol_write(c, p, p + NGX_PROXY_PROTOCOL_MAX_HEADER); + p = ngx_proxy_protocol_write(c, p, + p + NGX_PROXY_PROTOCOL_V1_MAX_HEADER); if (p == NULL) { ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR); return; @@ -946,14 +947,15 @@ ngx_stream_proxy_send_proxy_protocol(ngx_stream_session_t *s) ngx_connection_t *c, *pc; ngx_stream_upstream_t *u; ngx_stream_proxy_srv_conf_t *pscf; - u_char buf[NGX_PROXY_PROTOCOL_MAX_HEADER]; + u_char buf[NGX_PROXY_PROTOCOL_V1_MAX_HEADER]; c = s->connection; ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0, "stream proxy send PROXY protocol header"); - p = ngx_proxy_protocol_write(c, buf, buf + NGX_PROXY_PROTOCOL_MAX_HEADER); + p = ngx_proxy_protocol_write(c, buf, + buf + NGX_PROXY_PROTOCOL_V1_MAX_HEADER); if (p == NULL) { ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR); return NGX_ERROR; From fbe42d46312a87ee24f9038f26876a95c7abab34 Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Tue, 8 Nov 2022 12:48:19 +0300 Subject: [PATCH 03/17] Added logging to PROXY protocol write buffer check. The check is not expected to fail unless there is a bug in the calling code. But given the check is here, it should log an alert if it fails instead of silently closing the connection. --- src/core/ngx_proxy_protocol.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/core/ngx_proxy_protocol.c b/src/core/ngx_proxy_protocol.c index 212763647..8d3bd01d9 100644 --- a/src/core/ngx_proxy_protocol.c +++ b/src/core/ngx_proxy_protocol.c @@ -282,6 +282,8 @@ ngx_proxy_protocol_write(ngx_connection_t *c, u_char *buf, u_char *last) ngx_uint_t port, lport; if (last - buf < NGX_PROXY_PROTOCOL_V1_MAX_HEADER) { + ngx_log_error(NGX_LOG_ALERT, c->log, 0, + "too small buffer for PROXY protocol"); return NULL; } From 67e2a6916170f126a078bf7499a9a02c994e2f6d Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Tue, 8 Nov 2022 12:48:21 +0300 Subject: [PATCH 04/17] Fixed PROXY protocol to use ngx_memcpy()/ngx_memcmp(). --- src/core/ngx_proxy_protocol.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/core/ngx_proxy_protocol.c b/src/core/ngx_proxy_protocol.c index 8d3bd01d9..49888b986 100644 --- a/src/core/ngx_proxy_protocol.c +++ b/src/core/ngx_proxy_protocol.c @@ -109,7 +109,7 @@ ngx_proxy_protocol_read(ngx_connection_t *c, u_char *buf, u_char *last) len = last - buf; if (len >= sizeof(ngx_proxy_protocol_header_t) - && memcmp(p, signature, sizeof(signature) - 1) == 0) + && ngx_memcmp(p, signature, sizeof(signature) - 1) == 0) { return ngx_proxy_protocol_v2_read(c, buf, last); } @@ -396,11 +396,11 @@ ngx_proxy_protocol_v2_read(ngx_connection_t *c, u_char *buf, u_char *last) src_sockaddr.sockaddr_in.sin_family = AF_INET; src_sockaddr.sockaddr_in.sin_port = 0; - memcpy(&src_sockaddr.sockaddr_in.sin_addr, in->src_addr, 4); + ngx_memcpy(&src_sockaddr.sockaddr_in.sin_addr, in->src_addr, 4); dst_sockaddr.sockaddr_in.sin_family = AF_INET; dst_sockaddr.sockaddr_in.sin_port = 0; - memcpy(&dst_sockaddr.sockaddr_in.sin_addr, in->dst_addr, 4); + ngx_memcpy(&dst_sockaddr.sockaddr_in.sin_addr, in->dst_addr, 4); pp->src_port = ngx_proxy_protocol_parse_uint16(in->src_port); pp->dst_port = ngx_proxy_protocol_parse_uint16(in->dst_port); @@ -423,11 +423,11 @@ ngx_proxy_protocol_v2_read(ngx_connection_t *c, u_char *buf, u_char *last) src_sockaddr.sockaddr_in6.sin6_family = AF_INET6; src_sockaddr.sockaddr_in6.sin6_port = 0; - memcpy(&src_sockaddr.sockaddr_in6.sin6_addr, in6->src_addr, 16); + ngx_memcpy(&src_sockaddr.sockaddr_in6.sin6_addr, in6->src_addr, 16); dst_sockaddr.sockaddr_in6.sin6_family = AF_INET6; dst_sockaddr.sockaddr_in6.sin6_port = 0; - memcpy(&dst_sockaddr.sockaddr_in6.sin6_addr, in6->dst_addr, 16); + ngx_memcpy(&dst_sockaddr.sockaddr_in6.sin6_addr, in6->dst_addr, 16); pp->src_port = ngx_proxy_protocol_parse_uint16(in6->src_port); pp->dst_port = ngx_proxy_protocol_parse_uint16(in6->dst_port); From 053e40e5d45ac76ea29b803840222461f501f1e3 Mon Sep 17 00:00:00 2001 From: Ciel Zhao Date: Mon, 21 Nov 2022 17:01:34 +0300 Subject: [PATCH 05/17] SSI: handling of subrequests from other modules (ticket #1263). As the SSI parser always uses the context from the main request for storing variables and blocks, that context should always exist for subrequests using SSI, even though the main request does not necessarily have SSI enabled. However, `ngx_http_get_module_ctx(r->main, ...)` is getting NULL in such cases, resulting in the worker crashing SIGSEGV when accessing its attributes. This patch links the first initialized context to the main request, and upgrades it only when main context is initialized. --- src/http/modules/ngx_http_ssi_filter_module.c | 29 ++++++++++++++++++- src/http/modules/ngx_http_ssi_filter_module.h | 1 + 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/http/modules/ngx_http_ssi_filter_module.c b/src/http/modules/ngx_http_ssi_filter_module.c index 6737965d1..e7601b83e 100644 --- a/src/http/modules/ngx_http_ssi_filter_module.c +++ b/src/http/modules/ngx_http_ssi_filter_module.c @@ -329,7 +329,7 @@ static ngx_http_variable_t ngx_http_ssi_vars[] = { static ngx_int_t ngx_http_ssi_header_filter(ngx_http_request_t *r) { - ngx_http_ssi_ctx_t *ctx; + ngx_http_ssi_ctx_t *ctx, *mctx; ngx_http_ssi_loc_conf_t *slcf; slcf = ngx_http_get_module_loc_conf(r, ngx_http_ssi_filter_module); @@ -341,6 +341,8 @@ ngx_http_ssi_header_filter(ngx_http_request_t *r) return ngx_http_next_header_filter(r); } + mctx = ngx_http_get_module_ctx(r->main, ngx_http_ssi_filter_module); + ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_ssi_ctx_t)); if (ctx == NULL) { return NGX_ERROR; @@ -367,6 +369,26 @@ ngx_http_ssi_header_filter(ngx_http_request_t *r) r->filter_need_in_memory = 1; if (r == r->main) { + + if (mctx) { + + /* + * if there was a shared context previously used as main, + * copy variables and blocks + */ + + ctx->variables = mctx->variables; + ctx->blocks = mctx->blocks; + +#if (NGX_PCRE) + ctx->ncaptures = mctx->ncaptures; + ctx->captures = mctx->captures; + ctx->captures_data = mctx->captures_data; +#endif + + mctx->shared = 0; + } + ngx_http_clear_content_length(r); ngx_http_clear_accept_ranges(r); @@ -379,6 +401,10 @@ ngx_http_ssi_header_filter(ngx_http_request_t *r) } else { ngx_http_weak_etag(r); } + + } else if (mctx == NULL) { + ngx_http_set_ctx(r->main, ctx, ngx_http_ssi_filter_module); + ctx->shared = 1; } return ngx_http_next_header_filter(r); @@ -405,6 +431,7 @@ ngx_http_ssi_body_filter(ngx_http_request_t *r, ngx_chain_t *in) ctx = ngx_http_get_module_ctx(r, ngx_http_ssi_filter_module); if (ctx == NULL + || (ctx->shared && r == r->main) || (in == NULL && ctx->buf == NULL && ctx->in == NULL diff --git a/src/http/modules/ngx_http_ssi_filter_module.h b/src/http/modules/ngx_http_ssi_filter_module.h index 0bd01a067..419bf977d 100644 --- a/src/http/modules/ngx_http_ssi_filter_module.h +++ b/src/http/modules/ngx_http_ssi_filter_module.h @@ -71,6 +71,7 @@ typedef struct { u_char *captures_data; #endif + unsigned shared:1; unsigned conditional:2; unsigned encoding:2; unsigned block:1; From 17066ac8600412eabb1fdf8360cf6ada13f02391 Mon Sep 17 00:00:00 2001 From: Roman Arutyunyan Date: Fri, 18 Nov 2022 19:31:38 +0400 Subject: [PATCH 06/17] Process events posted by ngx_close_idle_connections() immediately. Previously, if an event was posted by a read event handler, called by ngx_close_idle_connections(), that event was not processed until the next event loop iteration, which could happen after a timeout. --- src/os/unix/ngx_process_cycle.c | 1 + src/os/win32/ngx_process_cycle.c | 1 + 2 files changed, 2 insertions(+) diff --git a/src/os/unix/ngx_process_cycle.c b/src/os/unix/ngx_process_cycle.c index 07cd05e80..821539bb7 100644 --- a/src/os/unix/ngx_process_cycle.c +++ b/src/os/unix/ngx_process_cycle.c @@ -736,6 +736,7 @@ ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data) ngx_set_shutdown_timer(cycle); ngx_close_listening_sockets(cycle); ngx_close_idle_connections(cycle); + ngx_event_process_posted(cycle, &ngx_posted_events); } } diff --git a/src/os/win32/ngx_process_cycle.c b/src/os/win32/ngx_process_cycle.c index 3aea874e0..0c848eff4 100644 --- a/src/os/win32/ngx_process_cycle.c +++ b/src/os/win32/ngx_process_cycle.c @@ -804,6 +804,7 @@ ngx_worker_thread(void *data) ngx_set_shutdown_timer(cycle); ngx_close_listening_sockets(cycle); ngx_close_idle_connections(cycle); + ngx_event_process_posted(cycle, &ngx_posted_events); } } From 22223c75c9715e568f5710a8eed1fee9e7c2983f Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Wed, 23 Nov 2022 17:30:08 +0300 Subject: [PATCH 07/17] Filtering duplicate addresses in listen (ticket #2400). Due to the glibc bug[1], getaddrinfo("localhost") with AI_ADDRCONFIG on a typical host with glibc and without IPv6 returns two 127.0.0.1 addresses, and therefore "listen localhost:80;" used to result in "duplicate ... address and port pair" after 4f9b72a229c1. Fix is to explicitly filter out duplicate addresses returned during resolution of a name. [1] https://sourceware.org/bugzilla/show_bug.cgi?id=14969 --- src/http/ngx_http_core_module.c | 15 ++++++++- src/mail/ngx_mail_core_module.c | 47 ++++++++++++++++++++------- src/stream/ngx_stream_core_module.c | 49 +++++++++++++++++++++-------- 3 files changed, 85 insertions(+), 26 deletions(-) diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c index 28f7d99b4..2647e7cd0 100644 --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -3963,7 +3963,7 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) ngx_str_t *value, size; ngx_url_t u; - ngx_uint_t n; + ngx_uint_t n, i; ngx_http_listen_opt_t lsopt; cscf->listen = 1; @@ -4289,6 +4289,16 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) } for (n = 0; n < u.naddrs; n++) { + + for (i = 0; i < n; i++) { + if (ngx_cmp_sockaddr(u.addrs[n].sockaddr, u.addrs[n].socklen, + u.addrs[i].sockaddr, u.addrs[i].socklen, 0) + == NGX_OK) + { + goto next; + } + } + lsopt.sockaddr = u.addrs[n].sockaddr; lsopt.socklen = u.addrs[n].socklen; lsopt.addr_text = u.addrs[n].name; @@ -4297,6 +4307,9 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) if (ngx_http_add_listen(cf, cscf, &lsopt) != NGX_OK) { return NGX_CONF_ERROR; } + + next: + continue; } return NGX_CONF_OK; diff --git a/src/mail/ngx_mail_core_module.c b/src/mail/ngx_mail_core_module.c index 115671ca4..75a2155db 100644 --- a/src/mail/ngx_mail_core_module.c +++ b/src/mail/ngx_mail_core_module.c @@ -308,7 +308,7 @@ ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) ngx_str_t *value, size; ngx_url_t u; ngx_uint_t i, n, m; - ngx_mail_listen_t *ls, *als; + ngx_mail_listen_t *ls, *als, *nls; ngx_mail_module_t *module; ngx_mail_core_main_conf_t *cmcf; @@ -333,7 +333,7 @@ ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) cmcf = ngx_mail_conf_get_module_main_conf(cf, ngx_mail_core_module); - ls = ngx_array_push_n(&cmcf->listen, u.naddrs); + ls = ngx_array_push(&cmcf->listen); if (ls == NULL) { return NGX_CONF_ERROR; } @@ -568,20 +568,40 @@ ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) return NGX_CONF_ERROR; } - als = cmcf->listen.elts; - for (n = 0; n < u.naddrs; n++) { - ls[n] = ls[0]; - ls[n].sockaddr = u.addrs[n].sockaddr; - ls[n].socklen = u.addrs[n].socklen; - ls[n].addr_text = u.addrs[n].name; - ls[n].wildcard = ngx_inet_wildcard(ls[n].sockaddr); + for (i = 0; i < n; i++) { + if (ngx_cmp_sockaddr(u.addrs[n].sockaddr, u.addrs[n].socklen, + u.addrs[i].sockaddr, u.addrs[i].socklen, 0) + == NGX_OK) + { + goto next; + } + } - for (i = 0; i < cmcf->listen.nelts - u.naddrs + n; i++) { + if (n != 0) { + nls = ngx_array_push(&cmcf->listen); + if (nls == NULL) { + return NGX_CONF_ERROR; + } + + *nls = *ls; + + } else { + nls = ls; + } + + nls->sockaddr = u.addrs[n].sockaddr; + nls->socklen = u.addrs[n].socklen; + nls->addr_text = u.addrs[n].name; + nls->wildcard = ngx_inet_wildcard(nls->sockaddr); + + als = cmcf->listen.elts; + + for (i = 0; i < cmcf->listen.nelts - 1; i++) { if (ngx_cmp_sockaddr(als[i].sockaddr, als[i].socklen, - ls[n].sockaddr, ls[n].socklen, 1) + nls->sockaddr, nls->socklen, 1) != NGX_OK) { continue; @@ -589,9 +609,12 @@ ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "duplicate \"%V\" address and port pair", - &ls[n].addr_text); + &nls->addr_text); return NGX_CONF_ERROR; } + + next: + continue; } return NGX_CONF_OK; diff --git a/src/stream/ngx_stream_core_module.c b/src/stream/ngx_stream_core_module.c index d96d27ab5..4be848570 100644 --- a/src/stream/ngx_stream_core_module.c +++ b/src/stream/ngx_stream_core_module.c @@ -578,7 +578,7 @@ ngx_stream_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) ngx_str_t *value, size; ngx_url_t u; ngx_uint_t i, n, backlog; - ngx_stream_listen_t *ls, *als; + ngx_stream_listen_t *ls, *als, *nls; ngx_stream_core_main_conf_t *cmcf; cscf->listen = 1; @@ -602,7 +602,7 @@ ngx_stream_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) cmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_core_module); - ls = ngx_array_push_n(&cmcf->listen, u.naddrs); + ls = ngx_array_push(&cmcf->listen); if (ls == NULL) { return NGX_CONF_ERROR; } @@ -886,23 +886,43 @@ ngx_stream_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) #endif } - als = cmcf->listen.elts; - for (n = 0; n < u.naddrs; n++) { - ls[n] = ls[0]; - ls[n].sockaddr = u.addrs[n].sockaddr; - ls[n].socklen = u.addrs[n].socklen; - ls[n].addr_text = u.addrs[n].name; - ls[n].wildcard = ngx_inet_wildcard(ls[n].sockaddr); + for (i = 0; i < n; i++) { + if (ngx_cmp_sockaddr(u.addrs[n].sockaddr, u.addrs[n].socklen, + u.addrs[i].sockaddr, u.addrs[i].socklen, 0) + == NGX_OK) + { + goto next; + } + } - for (i = 0; i < cmcf->listen.nelts - u.naddrs + n; i++) { - if (ls[n].type != als[i].type) { + if (n != 0) { + nls = ngx_array_push(&cmcf->listen); + if (nls == NULL) { + return NGX_CONF_ERROR; + } + + *nls = *ls; + + } else { + nls = ls; + } + + nls->sockaddr = u.addrs[n].sockaddr; + nls->socklen = u.addrs[n].socklen; + nls->addr_text = u.addrs[n].name; + nls->wildcard = ngx_inet_wildcard(nls->sockaddr); + + als = cmcf->listen.elts; + + for (i = 0; i < cmcf->listen.nelts - 1; i++) { + if (nls->type != als[i].type) { continue; } if (ngx_cmp_sockaddr(als[i].sockaddr, als[i].socklen, - ls[n].sockaddr, ls[n].socklen, 1) + nls->sockaddr, nls->socklen, 1) != NGX_OK) { continue; @@ -910,9 +930,12 @@ ngx_stream_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "duplicate \"%V\" address and port pair", - &ls[n].addr_text); + &nls->addr_text); return NGX_CONF_ERROR; } + + next: + continue; } return NGX_CONF_OK; From 593bb543873ac57efade09dbcc2f93ab6b4d5ab0 Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Wed, 23 Nov 2022 23:12:04 +0300 Subject: [PATCH 08/17] Disabled cloning of sockets without master process (ticket #2403). Cloning of listening sockets for each worker process does not make sense when working without master process, and causes some of the connections not to be accepted if worker_processes is set to more than one and there are listening sockets configured with the reuseport flag. Fix is to disable cloning when master process is disabled. --- src/event/ngx_event.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c index 47229b507..77b07f6e1 100644 --- a/src/event/ngx_event.c +++ b/src/event/ngx_event.c @@ -416,6 +416,7 @@ ngx_event_init_conf(ngx_cycle_t *cycle, void *conf) { #if (NGX_HAVE_REUSEPORT) ngx_uint_t i; + ngx_core_conf_t *ccf; ngx_listening_t *ls; #endif @@ -442,7 +443,9 @@ ngx_event_init_conf(ngx_cycle_t *cycle, void *conf) #if (NGX_HAVE_REUSEPORT) - if (!ngx_test_config) { + ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); + + if (!ngx_test_config && ccf->master) { ls = cycle->listening.elts; for (i = 0; i < cycle->listening.nelts; i++) { From d52e5684437aedd6bb74d6b2b602b7306f4212ba Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Wed, 23 Nov 2022 23:48:53 +0300 Subject: [PATCH 09/17] Fixed segfault when switching off master process during upgrade. Binary upgrades are not supported without master process, but it is, however, possible, that nginx running with master process is asked to upgrade binary, and the configuration file as available on disk at this time includes "master_process off;". If this happens, listening sockets inherited from the previous binary will have ls[i].previous set. But the old cycle on initial process startup, including startup after binary upgrade, is destroyed by ngx_init_cycle() once configuration parsing is complete. As a result, an attempt to dereference ls[i].previous in ngx_event_process_init() accesses already freed memory. Fix is to avoid looking into ls[i].previous if the old cycle is already freed. With this change it is also no longer needed to clear ls[i].previous in worker processes, so the relevant code was removed. --- src/event/ngx_event.c | 4 +++- src/os/unix/ngx_process_cycle.c | 10 ---------- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c index 77b07f6e1..d81547af4 100644 --- a/src/event/ngx_event.c +++ b/src/event/ngx_event.c @@ -813,7 +813,9 @@ ngx_event_process_init(ngx_cycle_t *cycle) rev->deferred_accept = ls[i].deferred_accept; #endif - if (!(ngx_event_flags & NGX_USE_IOCP_EVENT)) { + if (!(ngx_event_flags & NGX_USE_IOCP_EVENT) + && cycle->old_cycle) + { if (ls[i].previous) { /* diff --git a/src/os/unix/ngx_process_cycle.c b/src/os/unix/ngx_process_cycle.c index 821539bb7..98d2dd29b 100644 --- a/src/os/unix/ngx_process_cycle.c +++ b/src/os/unix/ngx_process_cycle.c @@ -759,7 +759,6 @@ ngx_worker_process_init(ngx_cycle_t *cycle, ngx_int_t worker) ngx_cpuset_t *cpu_affinity; struct rlimit rlmt; ngx_core_conf_t *ccf; - ngx_listening_t *ls; if (ngx_set_environment(cycle, NULL) == NULL) { /* fatal */ @@ -889,15 +888,6 @@ ngx_worker_process_init(ngx_cycle_t *cycle, ngx_int_t worker) tp = ngx_timeofday(); srandom(((unsigned) ngx_pid << 16) ^ tp->sec ^ tp->msec); - /* - * disable deleting previous events for the listening sockets because - * in the worker processes there are no events at all at this point - */ - ls = cycle->listening.elts; - for (i = 0; i < cycle->listening.nelts; i++) { - ls[i].previous = NULL; - } - for (i = 0; cycle->modules[i]; i++) { if (cycle->modules[i]->init_process) { if (cycle->modules[i]->init_process(cycle) == NGX_ERROR) { From 765ef1098d169622ada67eb4eccad1d45d47a61c Mon Sep 17 00:00:00 2001 From: Sergey Kandaurov Date: Thu, 24 Nov 2022 23:08:30 +0400 Subject: [PATCH 10/17] SSL: fixed debug logging of SSL_sendfile() return value. --- src/event/ngx_event_openssl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c index 3be64b6c2..702e8d877 100644 --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -3020,7 +3020,7 @@ ngx_ssl_sendfile(ngx_connection_t *c, ngx_buf_t *file, size_t size) n = SSL_sendfile(c->ssl->connection, file->file->fd, file->file_pos, size, flags); - ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_sendfile: %d", n); + ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_sendfile: %z", n); if (n > 0) { From e8da064e0d16527a994ec7e3b2937363804b8e30 Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Wed, 30 Nov 2022 18:01:43 +0300 Subject: [PATCH 11/17] Fixed alignment of ngx_memmove()/ngx_movemem() macro definitions. --- src/core/ngx_string.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/ngx_string.h b/src/core/ngx_string.h index 0fb9be72e..4378b649c 100644 --- a/src/core/ngx_string.h +++ b/src/core/ngx_string.h @@ -140,8 +140,8 @@ ngx_copy(u_char *dst, u_char *src, size_t len) #endif -#define ngx_memmove(dst, src, n) (void) memmove(dst, src, n) -#define ngx_movemem(dst, src, n) (((u_char *) memmove(dst, src, n)) + (n)) +#define ngx_memmove(dst, src, n) (void) memmove(dst, src, n) +#define ngx_movemem(dst, src, n) (((u_char *) memmove(dst, src, n)) + (n)) /* msvc and icc7 compile memcmp() to the inline loop */ From a77cef0995fb29af6602dcdeb560755443cb2cca Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Wed, 30 Nov 2022 18:01:53 +0300 Subject: [PATCH 12/17] Removed casts from ngx_memcmp() macro. Casts are believed to be not needed, since memcmp() has "const void *" arguments since introduction of the "void" type in C89. And on pre-C89 platforms nginx is unlikely to compile without warnings anyway, as there are no casts in memcpy() and memmove() calls. These casts were added in 1648:89a47f19b9ec without any details on why they were added, and Igor does not remember details either. The most plausible explanation is that they were copied from ngx_strcmp() and were not really needed even at that time. Prodded by Alejandro Colomar. --- src/core/ngx_string.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/ngx_string.h b/src/core/ngx_string.h index 4378b649c..713eb42a7 100644 --- a/src/core/ngx_string.h +++ b/src/core/ngx_string.h @@ -145,7 +145,7 @@ ngx_copy(u_char *dst, u_char *src, size_t len) /* msvc and icc7 compile memcmp() to the inline loop */ -#define ngx_memcmp(s1, s2, n) memcmp((const char *) s1, (const char *) s2, n) +#define ngx_memcmp(s1, s2, n) memcmp(s1, s2, n) u_char *ngx_cpystrn(u_char *dst, u_char *src, size_t n); From 39892c6265bb36604bbcbd5e315ec3ee0e91c277 Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Thu, 1 Dec 2022 04:22:31 +0300 Subject: [PATCH 13/17] SSL: fixed ngx_ssl_recv() to reset c->read->ready after errors. With this change, behaviour of ngx_ssl_recv() now matches ngx_unix_recv(), which used to always reset c->read->ready to 0 when returning errors. This fixes an infinite loop in unbuffered SSL proxying if writing to the client is blocked and an SSL error happens (ticket #2418). With this change, the fix for a similar issue in the stream module (6868:ee3645078759), which used a different approach of explicitly testing c->read->error instead, is no longer needed and was reverted. --- src/event/ngx_event_openssl.c | 5 +++++ src/stream/ngx_stream_proxy_module.c | 5 ++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c index 702e8d877..5f9ff5f0f 100644 --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -2204,6 +2204,7 @@ ngx_ssl_recv(ngx_connection_t *c, u_char *buf, size_t size) #endif if (c->ssl->last == NGX_ERROR) { + c->read->ready = 0; c->read->error = 1; return NGX_ERROR; } @@ -2270,6 +2271,7 @@ ngx_ssl_recv(ngx_connection_t *c, u_char *buf, size_t size) #if (NGX_HAVE_FIONREAD) if (ngx_socket_nread(c->fd, &c->read->available) == -1) { + c->read->ready = 0; c->read->error = 1; ngx_connection_error(c, ngx_socket_errno, ngx_socket_nread_n " failed"); @@ -2306,6 +2308,7 @@ ngx_ssl_recv(ngx_connection_t *c, u_char *buf, size_t size) return 0; case NGX_ERROR: + c->read->ready = 0; c->read->error = 1; /* fall through */ @@ -2326,6 +2329,7 @@ ngx_ssl_recv_early(ngx_connection_t *c, u_char *buf, size_t size) size_t readbytes; if (c->ssl->last == NGX_ERROR) { + c->read->ready = 0; c->read->error = 1; return NGX_ERROR; } @@ -2425,6 +2429,7 @@ ngx_ssl_recv_early(ngx_connection_t *c, u_char *buf, size_t size) return 0; case NGX_ERROR: + c->read->ready = 0; c->read->error = 1; /* fall through */ diff --git a/src/stream/ngx_stream_proxy_module.c b/src/stream/ngx_stream_proxy_module.c index e13d72f3a..eb2097621 100644 --- a/src/stream/ngx_stream_proxy_module.c +++ b/src/stream/ngx_stream_proxy_module.c @@ -1675,9 +1675,8 @@ ngx_stream_proxy_process(ngx_stream_session_t *s, ngx_uint_t from_upstream, size = b->end - b->last; - if (size && src->read->ready && !src->read->delayed - && !src->read->error) - { + if (size && src->read->ready && !src->read->delayed) { + if (limit_rate) { limit = (off_t) limit_rate * (ngx_time() - u->start_sec + 1) - *received; From 5eaa67490a43e4f1088b3ebf533559b424f207f1 Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Thu, 1 Dec 2022 04:22:36 +0300 Subject: [PATCH 14/17] Win32: event flags handling edge cases in ngx_wsarecv(). Fixed event flags handling edge cases in ngx_wsarecv() and ngx_wsarecv_chain(), notably to always reset rev->ready in case of errors (which wasn't the case after ngx_socket_nread() errors), and after EOF (rev->ready was not cleared if due to a misconfiguration a zero-sized buffer was used for reading). --- src/os/win32/ngx_wsarecv.c | 2 ++ src/os/win32/ngx_wsarecv_chain.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/os/win32/ngx_wsarecv.c b/src/os/win32/ngx_wsarecv.c index ac883107b..b01405e26 100644 --- a/src/os/win32/ngx_wsarecv.c +++ b/src/os/win32/ngx_wsarecv.c @@ -78,6 +78,7 @@ ngx_wsarecv(ngx_connection_t *c, u_char *buf, size_t size) ngx_socket_nread_n " failed"); if (n == NGX_ERROR) { + rev->ready = 0; rev->error = 1; } @@ -95,6 +96,7 @@ ngx_wsarecv(ngx_connection_t *c, u_char *buf, size_t size) } if (bytes == 0) { + rev->ready = 0; rev->eof = 1; } diff --git a/src/os/win32/ngx_wsarecv_chain.c b/src/os/win32/ngx_wsarecv_chain.c index 4f95d5a2b..e60389bb7 100644 --- a/src/os/win32/ngx_wsarecv_chain.c +++ b/src/os/win32/ngx_wsarecv_chain.c @@ -121,6 +121,7 @@ ngx_wsarecv_chain(ngx_connection_t *c, ngx_chain_t *chain, off_t limit) } else if (bytes == size) { if (ngx_socket_nread(c->fd, &rev->available) == -1) { + rev->ready = 0; rev->error = 1; ngx_connection_error(c, ngx_socket_errno, ngx_socket_nread_n " failed"); @@ -138,6 +139,7 @@ ngx_wsarecv_chain(ngx_connection_t *c, ngx_chain_t *chain, off_t limit) } if (bytes == 0) { + rev->ready = 0; rev->eof = 1; } From 3a52c79b44e93a9bc3878c8b6d364dfcd019ac85 Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Tue, 13 Dec 2022 03:32:57 +0300 Subject: [PATCH 15/17] Updated OpenSSL and zlib used for win32 builds. --- misc/GNUmakefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/GNUmakefile b/misc/GNUmakefile index d4a7ae531..8323e07b9 100644 --- a/misc/GNUmakefile +++ b/misc/GNUmakefile @@ -6,8 +6,8 @@ TEMP = tmp CC = cl OBJS = objs.msvc8 -OPENSSL = openssl-1.1.1q -ZLIB = zlib-1.2.12 +OPENSSL = openssl-1.1.1s +ZLIB = zlib-1.2.13 PCRE = pcre2-10.39 From 307123b35988d5fff3eadf544010ef585314a7a5 Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Tue, 13 Dec 2022 18:53:53 +0300 Subject: [PATCH 16/17] nginx-1.23.3-RELEASE --- docs/xml/nginx/changes.xml | 55 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/docs/xml/nginx/changes.xml b/docs/xml/nginx/changes.xml index 4e2e9a486..c3963fe7b 100644 --- a/docs/xml/nginx/changes.xml +++ b/docs/xml/nginx/changes.xml @@ -5,6 +5,61 @@ + + + + +при чтении заголовка протокола PROXY версии 2, содержащего +большое количество TLV, могла возникать ошибка. + + +an error might occur when reading PROXY protocol version 2 header +with large number of TLVs. + + + + + +при использовании SSI для обработки подзапросов, созданных другими модулями, +в рабочем процессе мог произойти segmentation fault.
+Спасибо Ciel Zhao. +
+ +a segmentation fault might occur in a worker process +if SSI was used to process subrequests created by other modules.
+Thanks to Ciel Zhao. +
+
+ + + +теперь, если при преобразовании в адреса имени хоста, +указанного в директиве listen, возвращается несколько адресов, +nginx игнорирует дубликаты среди этих адресов. + + +when a hostname used in the "listen" directive +resolves to multiple addresses, +nginx now ignores duplicates within these addresses. + + + + + +nginx мог нагружать процессор +при небуферизированном проксировании, +если использовались SSL-соединения с бэкендами. + + +nginx might hog CPU +during unbuffered proxying +if SSL connections to backends were used. + + + +
+ + From 8e9f7e89b819702532803f10f728b070f8ee2617 Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Tue, 13 Dec 2022 18:53:53 +0300 Subject: [PATCH 17/17] release-1.23.3 tag --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index a9108b3ec..79d46d2de 100644 --- a/.hgtags +++ b/.hgtags @@ -470,3 +470,4 @@ d986378168fd4d70e0121cabac274c560cca9bdf release-1.21.5 5da2c0902e8e2aa4534008a582a60c61c135960e release-1.23.0 a63d0a70afea96813ba6667997bc7d68b5863f0d release-1.23.1 aa901551a7ebad1e8b0f8c11cb44e3424ba29707 release-1.23.2 +ff3afd1ce6a6b65057741df442adfaa71a0e2588 release-1.23.3