Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package nginx for openSUSE:Factory checked in at 2026-03-25 21:17:22 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/nginx (Old) and /work/SRC/openSUSE:Factory/.nginx.new.8177 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "nginx" Wed Mar 25 21:17:22 2026 rev:109 rq:1342309 version:1.29.7 Changes: -------- --- /work/SRC/openSUSE:Factory/nginx/nginx.changes 2026-03-11 20:51:19.636106608 +0100 +++ /work/SRC/openSUSE:Factory/.nginx.new.8177/nginx.changes 2026-03-27 06:45:16.839511370 +0100 @@ -1,0 +2,32 @@ +Tue Mar 24 20:59:49 UTC 2026 - Илья Индиго <[email protected]> + +- Updated to 1.29.7 + * https://nginx.org/en/CHANGES + * Fixed a buffer overflow might occur while handling a COPY or MOVE + request in a location with "alias", allowing an attacker to modify + the source or destination path outside of the document root + (CVE-2026-27654) (boo#1260416). + * Fixed processing of a specially crafted mp4 file by the + ngx_http_mp4_module on 32-bit platforms might cause a worker process + crash, or might have potential other impact (CVE-2026-27784) (boo#1260417). + * Fixed processing of a specially crafted mp4 file by the + ngx_http_mp4_module might cause a worker process crash, or might have + potential other impact (CVE-2026-32647) (boo#1260420). + * Fixed a segmentation fault might occur in a worker process if the + CRAM-MD5 or APOP authentication methods were used and authentication + retry was enabled (CVE-2026-27651) (boo#1260415). + * Fixed an attacker might use PTR DNS records to inject data in + auth_http requests, as well as in the XCLIENT command in the backend + SMTP connection (CVE-2026-28753) (boo#1260418). + * Fixed SSL handshake might succeed despite OCSP rejecting a client + certificate in the stream module (CVE-2026-28755) (boo#1260419). + * Fixed an invalid HTTP/2 request might be sent after switching to the + next upstream if buffered body was used in the ngx_http_grpc_module. + * Changed now the "keepalive" directive in the "upstream" block is enabled by default. + * Changed now ngx_http_proxy_module supports keepalive by default; the + default value for "proxy_http_version" is "1.1"; the "Connection" + proxy header is not sent by default anymore. + * Added the "multipath" parameter of the "listen" directive. + * Added the "local" parameter of the "keepalive" directive in the "upstream" block. + +------------------------------------------------------------------- @@ -26 +58,2 @@ - * Fixed an attacker might inject plain text data in the response from an SSL backend (CVE-2026-1642). + * Fixed an attacker might inject plain text data in the response from an SSL backend + (CVE-2026-1642) (boo#1257675). @@ -92 +125 @@ - (CVE-2025-53859). + (CVE-2025-53859) (boo#1248070). @@ -173 +206 @@ - bypass client SSL certificates verification (CVE-2025-23419). + bypass client SSL certificates verification (CVE-2025-23419) (boo#1236851). @@ -224 +257,2 @@ - * Fixed crash in ngx_http_mp4_module via specially crafted mp4 file (CVE-2024-7347). + * Fixed crash in ngx_http_mp4_module via specially crafted mp4 file + (CVE-2024-7347) (boo#1229155). @@ -279 +313,2 @@ - processing a specially crafted QUIC session (CVE-2024-24989, CVE-2024-24990). + processing a specially crafted QUIC session + (CVE-2024-24989 CVE-2024-24990) (boo#1219951 boo#1219952). @@ -364 +399 @@ - (CVE-2022-41741, CVE-2022-41742). + (CVE-2022-41741 CVE-2022-41742) (boo#1204526 boo#1204527). Old: ---- nginx-1.29.6.tar.gz nginx-1.29.6.tar.gz.asc New: ---- nginx-1.29.7.tar.gz nginx-1.29.7.tar.gz.asc ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ nginx.spec ++++++ --- /var/tmp/diff_new_pack.ZUgxr5/_old 2026-03-27 06:45:17.639544394 +0100 +++ /var/tmp/diff_new_pack.ZUgxr5/_new 2026-03-27 06:45:17.643544559 +0100 @@ -23,7 +23,7 @@ %bcond_with ngx_google_perftools # Name: nginx -Version: 1.29.6 +Version: 1.29.7 Release: 0 Summary: A HTTP server and IMAP/POP3 proxy server License: BSD-2-Clause ++++++ nginx-1.29.6.tar.gz -> nginx-1.29.7.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.6/CHANGES new/nginx-1.29.7/CHANGES --- old/nginx-1.29.6/CHANGES 2026-03-10 16:34:24.000000000 +0100 +++ new/nginx-1.29.7/CHANGES 2026-03-24 17:21:01.000000000 +0100 @@ -1,4 +1,56 @@ +Changes with nginx 1.29.7 24 Mar 2026 + + *) Security: a buffer overflow might occur while handling a COPY or MOVE + request in a location with "alias", allowing an attacker to modify + the source or destination path outside of the document root + (CVE-2026-27654). + Thanks to Calif.io in collaboration with Claude and Anthropic + Research. + + *) Security: processing of a specially crafted mp4 file by the + ngx_http_mp4_module on 32-bit platforms might cause a worker process + crash, or might have potential other impact (CVE-2026-27784). + Thanks to Prabhav Srinath (sprabhav7). + + *) Security: processing of a specially crafted mp4 file by the + ngx_http_mp4_module might cause a worker process crash, or might have + potential other impact (CVE-2026-32647). + Thanks to Xint Code and Pavel Kohout (Aisle Research). + + *) Security: a segmentation fault might occur in a worker process if the + CRAM-MD5 or APOP authentication methods were used and authentication + retry was enabled (CVE-2026-27651). + Thanks to Arkadi Vainbrand. + + *) Security: an attacker might use PTR DNS records to inject data in + auth_http requests, as well as in the XCLIENT command in the backend + SMTP connection (CVE-2026-28753). + Thanks to Asim Viladi Oglu Manizada, Colin Warren, Xiao Liu (Yunnan + University), Yuan Tan (UC Riverside), and Bird Liu (Lanzhou + University). + + *) Security: SSL handshake might succeed despite OCSP rejecting a client + certificate in the stream module (CVE-2026-28755). + Thanks to Mufeed VH of Winfunc Research. + + *) Feature: the "multipath" parameter of the "listen" directive. + + *) Feature: the "local" parameter of the "keepalive" directive in the + "upstream" block. + + *) Change: now the "keepalive" directive in the "upstream" block is + enabled by default. + + *) Change: now ngx_http_proxy_module supports keepalive by default; the + default value for "proxy_http_version" is "1.1"; the "Connection" + proxy header is not sent by default anymore. + + *) Bugfix: an invalid HTTP/2 request might be sent after switching to + the next upstream if buffered body was used in the + ngx_http_grpc_module. + + Changes with nginx 1.29.6 10 Mar 2026 *) Feature: session affinity support; the "sticky" directive in the diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.6/CHANGES.ru new/nginx-1.29.7/CHANGES.ru --- old/nginx-1.29.6/CHANGES.ru 2026-03-10 16:34:24.000000000 +0100 +++ new/nginx-1.29.7/CHANGES.ru 2026-03-24 17:21:00.000000000 +0100 @@ -1,4 +1,54 @@ +Изменения в nginx 1.29.7 24.03.2026 + + *) Безопасность: при обработке COPY- или MOVE-запроса в location'е с + включённым alias могло произойти переполнение буфера, что позволяло + атакующему модифицировать исходный или целевой путь за пределы + document root (CVE-2026-27654). + Спасибо Calif.io при содействии Claude и Anthropic Research. + + *) Безопасность: обработка специально созданного mp4-файла модулем + ngx_http_mp4_module на 32-битных платформах могла приводить к падению + рабочего процесса, а также потенциально могла иметь другие + последствия (CVE-2026-27784). + Спасибо Prabhav Srinath (sprabhav7). + + *) Безопасность: обработка специально созданного mp4-файла модулем + ngx_http_mp4_module могла приводить к падению рабочего процесса, а + также потенциально могла иметь другие последствия (CVE-2026-32647). + Спасибо Xint Code и Pavel Kohout (Aisle Research). + + *) Безопасность: если использовался метод аутентификации CRAM-MD5 или + APOP, то в рабочем процессе мог произойти segmentation fault, если + были разрешены повторные попытки аутентификации (CVE-2026-27651). + Спасибо Arkadi Vainbrand. + + *) Безопасность: атакующий мог использовать записи PTR DNS чтобы + вставить данные в auth_http-запросы, а также в команду XCLIENT в + SMTP-соединении к бекенду (CVE-2026-28753). + Спасибо Asim Viladi Oglu Manizada, Colin Warren, Xiao Liu (Yunnan + University), Yuan Tan (UC Riverside) и Bird Liu (Lanzhou University). + + *) Безопасность: SSL handshake мог завершиться успешно при том, что OCSP + отклонил клиентский сертификат в модуле stream (CVE-2026-28755). + Спасибо Mufeed VH из Winfunc Research. + + *) Добавление: параметр multipath директивы listen. + + *) Добавление: параметр local директивы keepalive в блоке upstream. + + *) Изменение: теперь директива keepalive в блоке upstream включена по + умолчанию. + + *) Изменение: теперь модуль ngx_http_proxy_module поддерживает keepalive + по умолчанию; значение proxy_http_version по умолчанию равно "1.1"; + proxy заголовок "Connection" по умолчанию больше не посылается. + + *) Исправление: некорректный HTTP/2-запрос мог быть отправлен после + переключения на следующий бэкенд при использовании буферизованного + тела в модуле ngx_http_grpc_module. + + Изменения в nginx 1.29.6 10.03.2026 *) Добавление: режим привязки сессий; директива sticky в блоке upstream diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.6/contrib/vim/syntax/nginx.vim new/nginx-1.29.7/contrib/vim/syntax/nginx.vim --- old/nginx-1.29.6/contrib/vim/syntax/nginx.vim 2026-03-10 16:29:07.000000000 +0100 +++ new/nginx-1.29.7/contrib/vim/syntax/nginx.vim 2026-03-24 16:38:34.000000000 +0100 @@ -65,7 +65,7 @@ \ contained \ nextgroup=@ngxListenParams skipwhite skipempty syn keyword ngxListenOptions contained - \ default_server ssl quic proxy_protocol + \ default_server ssl quic proxy_protocol multipath \ setfib fastopen backlog rcvbuf sndbuf accept_filter deferred bind \ ipv6only reuseport so_keepalive \ nextgroup=@ngxListenParams skipwhite skipempty diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.6/src/core/nginx.h new/nginx-1.29.7/src/core/nginx.h --- old/nginx-1.29.6/src/core/nginx.h 2026-03-10 16:29:07.000000000 +0100 +++ new/nginx-1.29.7/src/core/nginx.h 2026-03-24 16:38:34.000000000 +0100 @@ -9,8 +9,8 @@ #define _NGINX_H_INCLUDED_ -#define nginx_version 1029006 -#define NGINX_VERSION "1.29.6" +#define nginx_version 1029007 +#define NGINX_VERSION "1.29.7" #define NGINX_VER "nginx/" NGINX_VERSION #ifdef NGX_BUILD diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.6/src/core/ngx_connection.c new/nginx-1.29.7/src/core/ngx_connection.c --- old/nginx-1.29.6/src/core/ngx_connection.c 2026-03-10 16:29:07.000000000 +0100 +++ new/nginx-1.29.7/src/core/ngx_connection.c 2026-03-24 16:38:34.000000000 +0100 @@ -315,6 +315,25 @@ continue; } +#ifdef SO_PROTOCOL + + olen = sizeof(int); + + if (getsockopt(ls[i].fd, SOL_SOCKET, SO_PROTOCOL, + (void *) &ls[i].protocol, &olen) + == -1) + { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_socket_errno, + "getsockopt(SO_PROTOCOL) %V failed, ignored", + &ls[i].addr_text); + ls[i].protocol = 0; + + } else if (ls[i].protocol == IPPROTO_TCP) { + ls[i].protocol = 0; + } + +#endif + #if (NGX_HAVE_TCP_FASTOPEN) olen = sizeof(int); @@ -436,12 +455,16 @@ #if (NGX_HAVE_REUSEPORT) - if (ls[i].add_reuseport) { + if (ls[i].add_reuseport || ls[i].change_protocol) { /* * to allow transition from a socket without SO_REUSEPORT * to multiple sockets with SO_REUSEPORT, we have to set * SO_REUSEPORT on the old socket before opening new ones + * + * to allow transition between different socket protocols + * (e.g. IPPROTO_MPTCP), SO_REUSEPORT is set on both old + * and new sockets */ int reuseport = 1; @@ -474,7 +497,7 @@ } #endif - if (ls[i].fd != (ngx_socket_t) -1) { + if (ls[i].fd != (ngx_socket_t) -1 && !ls[i].change_protocol) { continue; } @@ -487,7 +510,8 @@ continue; } - s = ngx_socket(ls[i].sockaddr->sa_family, ls[i].type, 0); + s = ngx_socket(ls[i].sockaddr->sa_family, ls[i].type, + ls[i].protocol); if (s == (ngx_socket_t) -1) { ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, @@ -517,7 +541,9 @@ #if (NGX_HAVE_REUSEPORT) - if (ls[i].reuseport && !ngx_test_config) { + if ((ls[i].reuseport || ls[i].change_protocol) + && !ngx_test_config) + { int reuseport; reuseport = 1; @@ -651,6 +677,7 @@ if (ls[i].type != SOCK_STREAM) { ls[i].fd = s; + ls[i].open = 1; continue; } @@ -689,6 +716,7 @@ ls[i].listen = 1; ls[i].fd = s; + ls[i].open = 1; } if (!failed) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.6/src/core/ngx_connection.h new/nginx-1.29.7/src/core/ngx_connection.h --- old/nginx-1.29.6/src/core/ngx_connection.h 2026-03-10 16:29:07.000000000 +0100 +++ new/nginx-1.29.7/src/core/ngx_connection.h 2026-03-24 16:38:34.000000000 +0100 @@ -24,6 +24,7 @@ ngx_str_t addr_text; int type; + int protocol; int backlog; int rcvbuf; @@ -75,6 +76,8 @@ unsigned keepalive:2; unsigned quic:1; + unsigned change_protocol:1; + unsigned deferred_accept:1; unsigned delete_deferred:1; unsigned add_deferred:1; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.6/src/core/ngx_cycle.c new/nginx-1.29.7/src/core/ngx_cycle.c --- old/nginx-1.29.6/src/core/ngx_cycle.c 2026-03-10 16:29:07.000000000 +0100 +++ new/nginx-1.29.7/src/core/ngx_cycle.c 2026-03-24 16:38:34.000000000 +0100 @@ -535,9 +535,15 @@ == NGX_OK) { nls[n].fd = ls[i].fd; - nls[n].inherited = ls[i].inherited; nls[n].previous = &ls[i]; - ls[i].remain = 1; + + if (ls[i].protocol != nls[n].protocol) { + nls[n].change_protocol = 1; + + } else { + nls[n].inherited = ls[i].inherited; + ls[i].remain = 1; + } if (ls[i].backlog != nls[n].backlog) { nls[n].listen = 1; @@ -590,7 +596,6 @@ } if (nls[n].fd == (ngx_socket_t) -1) { - nls[n].open = 1; #if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER) if (nls[n].accept_filter) { nls[n].add_deferred = 1; @@ -605,20 +610,21 @@ } } else { +#if (NGX_HAVE_DEFERRED_ACCEPT) ls = cycle->listening.elts; for (i = 0; i < cycle->listening.nelts; i++) { - ls[i].open = 1; -#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER) +#ifdef SO_ACCEPTFILTER if (ls[i].accept_filter) { ls[i].add_deferred = 1; } #endif -#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT) +#ifdef TCP_DEFER_ACCEPT if (ls[i].deferred_accept) { ls[i].add_deferred = 1; } #endif } +#endif } if (ngx_open_listening_sockets(cycle) != NGX_OK) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.6/src/core/ngx_log.h new/nginx-1.29.7/src/core/ngx_log.h --- old/nginx-1.29.6/src/core/ngx_log.h 2026-03-10 16:29:07.000000000 +0100 +++ new/nginx-1.29.7/src/core/ngx_log.h 2026-03-24 16:38:34.000000000 +0100 @@ -70,6 +70,9 @@ char *action; ngx_log_t *next; + + NGX_COMPAT_BEGIN(5) + NGX_COMPAT_END }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.6/src/http/modules/ngx_http_dav_module.c new/nginx-1.29.7/src/http/modules/ngx_http_dav_module.c --- old/nginx-1.29.6/src/http/modules/ngx_http_dav_module.c 2026-03-10 16:29:07.000000000 +0100 +++ new/nginx-1.29.7/src/http/modules/ngx_http_dav_module.c 2026-03-24 16:38:34.000000000 +0100 @@ -535,19 +535,20 @@ static ngx_int_t ngx_http_dav_copy_move_handler(ngx_http_request_t *r) { - u_char *p, *host, *last, ch; - size_t len, root; - ngx_err_t err; - ngx_int_t rc, depth; - ngx_uint_t overwrite, slash, dir, flags; - ngx_str_t path, uri, duri, args; - ngx_tree_ctx_t tree; - ngx_copy_file_t cf; - ngx_file_info_t fi; - ngx_table_elt_t *dest, *over; - ngx_ext_rename_file_t ext; - ngx_http_dav_copy_ctx_t copy; - ngx_http_dav_loc_conf_t *dlcf; + u_char *p, *host, *last, ch; + size_t len, root; + ngx_err_t err; + ngx_int_t rc, depth; + ngx_uint_t overwrite, slash, dir, flags; + ngx_str_t path, uri, duri, args; + ngx_tree_ctx_t tree; + ngx_copy_file_t cf; + ngx_file_info_t fi; + ngx_table_elt_t *dest, *over; + ngx_ext_rename_file_t ext; + ngx_http_dav_copy_ctx_t copy; + ngx_http_dav_loc_conf_t *dlcf; + ngx_http_core_loc_conf_t *clcf; if (r->headers_in.content_length_n > 0 || r->headers_in.chunked) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, @@ -644,6 +645,18 @@ return NGX_HTTP_CONFLICT; } + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + + if (clcf->alias + && clcf->alias != NGX_MAX_SIZE_T_VALUE + && duri.len < clcf->alias) + { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "client sent invalid \"Destination\" header: \"%V\"", + &dest->value); + return NGX_HTTP_BAD_REQUEST; + } + depth = ngx_http_dav_depth(r, NGX_HTTP_DAV_INFINITY_DEPTH); if (depth != NGX_HTTP_DAV_INFINITY_DEPTH) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.6/src/http/modules/ngx_http_grpc_module.c new/nginx-1.29.7/src/http/modules/ngx_http_grpc_module.c --- old/nginx-1.29.6/src/http/modules/ngx_http_grpc_module.c 2026-03-10 16:29:07.000000000 +0100 +++ new/nginx-1.29.7/src/http/modules/ngx_http_grpc_module.c 2026-03-24 16:38:34.000000000 +0100 @@ -1224,6 +1224,9 @@ ctx->rst = 0; ctx->goaway = 0; ctx->connection = NULL; + ctx->in = NULL; + ctx->busy = NULL; + ctx->out = NULL; return NGX_OK; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.6/src/http/modules/ngx_http_mp4_module.c new/nginx-1.29.7/src/http/modules/ngx_http_mp4_module.c --- old/nginx-1.29.6/src/http/modules/ngx_http_mp4_module.c 2026-03-10 16:29:07.000000000 +0100 +++ new/nginx-1.29.7/src/http/modules/ngx_http_mp4_module.c 2026-03-24 16:38:34.000000000 +0100 @@ -901,8 +901,11 @@ } } - if (end_offset < start_offset) { - end_offset = start_offset; + if (end_offset <= start_offset) { + ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, + "no data between start time and end time in \"%s\"", + mp4->file.name.data); + return NGX_ERROR; } mp4->moov_size += 8; @@ -913,7 +916,7 @@ *prev = &mp4->mdat_atom; - if (start_offset > mp4->mdat_data.buf->file_last) { + if (start_offset >= mp4->mdat_data.buf->file_last) { ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, "start time is out mp4 mdat atom in \"%s\"", mp4->file.name.data); @@ -2294,7 +2297,7 @@ "mp4 time-to-sample entries:%uD", entries); if (ngx_mp4_atom_data_size(ngx_mp4_stts_atom_t) - + entries * sizeof(ngx_mp4_stts_entry_t) > atom_data_size) + + (uint64_t) entries * sizeof(ngx_mp4_stts_entry_t) > atom_data_size) { ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, "\"%s\" mp4 stts atom too small", mp4->file.name.data); @@ -2609,7 +2612,7 @@ atom->last = atom_table; if (ngx_mp4_atom_data_size(ngx_http_mp4_stss_atom_t) - + entries * sizeof(uint32_t) > atom_data_size) + + (uint64_t) entries * sizeof(uint32_t) > atom_data_size) { ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, "\"%s\" mp4 stss atom too small", mp4->file.name.data); @@ -2814,7 +2817,7 @@ atom->last = atom_table; if (ngx_mp4_atom_data_size(ngx_mp4_ctts_atom_t) - + entries * sizeof(ngx_mp4_ctts_entry_t) > atom_data_size) + + (uint64_t) entries * sizeof(ngx_mp4_ctts_entry_t) > atom_data_size) { ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, "\"%s\" mp4 ctts atom too small", mp4->file.name.data); @@ -2996,7 +2999,7 @@ "sample-to-chunk entries:%uD", entries); if (ngx_mp4_atom_data_size(ngx_mp4_stsc_atom_t) - + entries * sizeof(ngx_mp4_stsc_entry_t) > atom_data_size) + + (uint64_t) entries * sizeof(ngx_mp4_stsc_entry_t) > atom_data_size) { ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, "\"%s\" mp4 stsc atom too small", mp4->file.name.data); @@ -3390,7 +3393,7 @@ if (size == 0) { if (ngx_mp4_atom_data_size(ngx_mp4_stsz_atom_t) - + entries * sizeof(uint32_t) > atom_data_size) + + (uint64_t) entries * sizeof(uint32_t) > atom_data_size) { ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, "\"%s\" mp4 stsz atom too small", @@ -3444,7 +3447,7 @@ if (data) { entries = trak->sample_sizes_entries; - if (trak->start_sample > entries) { + if (trak->start_sample >= entries) { ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, "start time is out mp4 stsz samples in \"%s\"", mp4->file.name.data); @@ -3549,7 +3552,7 @@ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "chunks:%uD", entries); if (ngx_mp4_atom_data_size(ngx_mp4_stco_atom_t) - + entries * sizeof(uint32_t) > atom_data_size) + + (uint64_t) entries * sizeof(uint32_t) > atom_data_size) { ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, "\"%s\" mp4 stco atom too small", mp4->file.name.data); @@ -3619,7 +3622,7 @@ return NGX_ERROR; } - if (trak->start_chunk > trak->chunks) { + if (trak->start_chunk >= trak->chunks) { ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, "start time is out mp4 stco chunks in \"%s\"", mp4->file.name.data); @@ -3765,7 +3768,7 @@ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "chunks:%uD", entries); if (ngx_mp4_atom_data_size(ngx_mp4_co64_atom_t) - + entries * sizeof(uint64_t) > atom_data_size) + + (uint64_t) entries * sizeof(uint64_t) > atom_data_size) { ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, "\"%s\" mp4 co64 atom too small", mp4->file.name.data); @@ -3834,7 +3837,7 @@ return NGX_ERROR; } - if (trak->start_chunk > trak->chunks) { + if (trak->start_chunk >= trak->chunks) { ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, "start time is out mp4 co64 chunks in \"%s\"", mp4->file.name.data); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.6/src/http/modules/ngx_http_proxy_module.c new/nginx-1.29.7/src/http/modules/ngx_http_proxy_module.c --- old/nginx-1.29.6/src/http/modules/ngx_http_proxy_module.c 2026-03-10 16:29:07.000000000 +0100 +++ new/nginx-1.29.7/src/http/modules/ngx_http_proxy_module.c 2026-03-24 16:38:34.000000000 +0100 @@ -85,9 +85,6 @@ ngx_http_proxy_add_x_forwarded_for_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t - ngx_http_proxy_internal_connection_variable(ngx_http_request_t *r, - ngx_http_variable_value_t *v, uintptr_t data); -static ngx_int_t ngx_http_proxy_internal_body_length_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_proxy_internal_chunked_variable(ngx_http_request_t *r, @@ -749,7 +746,7 @@ static ngx_keyval_t ngx_http_proxy_headers[] = { { ngx_string("Host"), ngx_string("$proxy_internal_host") }, - { ngx_string("Connection"), ngx_string("$proxy_internal_connection") }, + { ngx_string("Connection"), ngx_string("") }, { ngx_string("Content-Length"), ngx_string("$proxy_internal_body_length") }, { ngx_string("Transfer-Encoding"), ngx_string("$proxy_internal_chunked") }, { ngx_string("TE"), ngx_string("") }, @@ -777,7 +774,7 @@ static ngx_keyval_t ngx_http_proxy_cache_headers[] = { { ngx_string("Host"), ngx_string("$proxy_internal_host") }, - { ngx_string("Connection"), ngx_string("$proxy_internal_connection") }, + { ngx_string("Connection"), ngx_string("") }, { ngx_string("Content-Length"), ngx_string("$proxy_internal_body_length") }, { ngx_string("Transfer-Encoding"), ngx_string("$proxy_internal_chunked") }, { ngx_string("TE"), ngx_string("") }, @@ -816,10 +813,6 @@ ngx_http_proxy_host_variable, 1, NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_NOHASH, 0 }, - { ngx_string("proxy_internal_connection"), NULL, - ngx_http_proxy_internal_connection_variable, 0, - NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_NOHASH, 0 }, - { ngx_string("proxy_internal_body_length"), NULL, ngx_http_proxy_internal_body_length_variable, 0, NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_NOHASH, 0 }, @@ -2778,29 +2771,6 @@ static ngx_int_t -ngx_http_proxy_internal_connection_variable(ngx_http_request_t *r, - ngx_http_variable_value_t *v, uintptr_t data) -{ - ngx_http_proxy_ctx_t *ctx; - - ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module); - - if (ctx == NULL || !ctx->legacy) { - v->not_found = 1; - return NGX_OK; - } - - v->valid = 1; - v->no_cacheable = 0; - v->not_found = 0; - - ngx_str_set(v, "close"); - - return NGX_OK; -} - - -static ngx_int_t ngx_http_proxy_internal_body_length_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data) { @@ -4030,7 +4000,7 @@ ngx_conf_merge_ptr_value(conf->cookie_flags, prev->cookie_flags, NULL); ngx_conf_merge_uint_value(conf->http_version, prev->http_version, - NGX_HTTP_VERSION_10); + NGX_HTTP_VERSION_11); ngx_conf_merge_uint_value(conf->headers_hash_max_size, prev->headers_hash_max_size, 512); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.6/src/http/modules/ngx_http_proxy_v2_module.c new/nginx-1.29.7/src/http/modules/ngx_http_proxy_v2_module.c --- old/nginx-1.29.6/src/http/modules/ngx_http_proxy_v2_module.c 2026-03-10 16:29:07.000000000 +0100 +++ new/nginx-1.29.7/src/http/modules/ngx_http_proxy_v2_module.c 2026-03-24 16:38:34.000000000 +0100 @@ -946,6 +946,7 @@ ctx->connection = NULL; ctx->in = NULL; ctx->busy = NULL; + ctx->out = NULL; return NGX_OK; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.6/src/http/modules/ngx_http_upstream_keepalive_module.c new/nginx-1.29.7/src/http/modules/ngx_http_upstream_keepalive_module.c --- old/nginx-1.29.6/src/http/modules/ngx_http_upstream_keepalive_module.c 2026-03-10 16:29:07.000000000 +0100 +++ new/nginx-1.29.7/src/http/modules/ngx_http_upstream_keepalive_module.c 2026-03-24 16:38:34.000000000 +0100 @@ -19,9 +19,10 @@ ngx_queue_t cache; ngx_queue_t free; - ngx_http_upstream_init_pt original_init_upstream; ngx_http_upstream_init_peer_pt original_init_peer; + ngx_uint_t local; /* unsigned local:1; */ + } ngx_http_upstream_keepalive_srv_conf_t; @@ -34,6 +35,8 @@ socklen_t socklen; ngx_sockaddr_t sockaddr; + ngx_http_upstream_conf_t *tag; + } ngx_http_upstream_keepalive_cache_t; @@ -79,6 +82,8 @@ void *data, ngx_uint_t type); static void *ngx_http_upstream_keepalive_create_conf(ngx_conf_t *cf); +static char *ngx_http_upstream_keepalive_init_main_conf(ngx_conf_t *cf, + void *conf); static char *ngx_http_upstream_keepalive(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); @@ -86,7 +91,7 @@ static ngx_command_t ngx_http_upstream_keepalive_commands[] = { { ngx_string("keepalive"), - NGX_HTTP_UPS_CONF|NGX_CONF_TAKE1, + NGX_HTTP_UPS_CONF|NGX_CONF_TAKE12, ngx_http_upstream_keepalive, NGX_HTTP_SRV_CONF_OFFSET, 0, @@ -122,7 +127,7 @@ NULL, /* postconfiguration */ NULL, /* create main configuration */ - NULL, /* init main configuration */ + ngx_http_upstream_keepalive_init_main_conf, /* init main configuration */ ngx_http_upstream_keepalive_create_conf, /* create server configuration */ NULL, /* merge server configuration */ @@ -149,52 +154,6 @@ static ngx_int_t -ngx_http_upstream_init_keepalive(ngx_conf_t *cf, - ngx_http_upstream_srv_conf_t *us) -{ - ngx_uint_t i; - ngx_http_upstream_keepalive_srv_conf_t *kcf; - ngx_http_upstream_keepalive_cache_t *cached; - - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, cf->log, 0, - "init keepalive"); - - kcf = ngx_http_conf_upstream_srv_conf(us, - ngx_http_upstream_keepalive_module); - - ngx_conf_init_msec_value(kcf->time, 3600000); - ngx_conf_init_msec_value(kcf->timeout, 60000); - ngx_conf_init_uint_value(kcf->requests, 1000); - - if (kcf->original_init_upstream(cf, us) != NGX_OK) { - return NGX_ERROR; - } - - kcf->original_init_peer = us->peer.init; - - us->peer.init = ngx_http_upstream_init_keepalive_peer; - - /* allocate cache items and add to free queue */ - - cached = ngx_pcalloc(cf->pool, - sizeof(ngx_http_upstream_keepalive_cache_t) * kcf->max_cached); - if (cached == NULL) { - return NGX_ERROR; - } - - ngx_queue_init(&kcf->cache); - ngx_queue_init(&kcf->free); - - for (i = 0; i < kcf->max_cached; i++) { - ngx_queue_insert_head(&kcf->free, &cached[i].queue); - cached[i].conf = kcf; - } - - return NGX_OK; -} - - -static ngx_int_t ngx_http_upstream_init_keepalive_peer(ngx_http_request_t *r, ngx_http_upstream_srv_conf_t *us) { @@ -274,6 +233,10 @@ item = ngx_queue_data(q, ngx_http_upstream_keepalive_cache_t, queue); c = item->connection; + if (kp->conf->local && item->tag != kp->upstream->conf) { + continue; + } + if (ngx_memn2cmp((u_char *) &item->sockaddr, (u_char *) pc->sockaddr, item->socklen, pc->socklen) == 0) @@ -387,6 +350,7 @@ ngx_queue_insert_head(&kp->conf->cache, q); item->connection = c; + item->tag = u->conf; pc->connection = NULL; @@ -541,29 +505,89 @@ /* * set by ngx_pcalloc(): * - * conf->original_init_upstream = NULL; * conf->original_init_peer = NULL; - * conf->max_cached = 0; + * conf->local = 0; */ conf->time = NGX_CONF_UNSET_MSEC; conf->timeout = NGX_CONF_UNSET_MSEC; conf->requests = NGX_CONF_UNSET_UINT; + conf->max_cached = NGX_CONF_UNSET_UINT; return conf; } static char * +ngx_http_upstream_keepalive_init_main_conf(ngx_conf_t *cf, void *conf) +{ + ngx_uint_t i, j; + ngx_http_upstream_srv_conf_t **uscfp; + ngx_http_upstream_main_conf_t *umcf; + ngx_http_upstream_keepalive_cache_t *cached; + ngx_http_upstream_keepalive_srv_conf_t *kcf; + + umcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_upstream_module); + + uscfp = umcf->upstreams.elts; + + for (i = 0; i < umcf->upstreams.nelts; i++) { + + /* skip implicit upstreams */ + if (uscfp[i]->srv_conf == NULL) { + continue; + } + + kcf = ngx_http_conf_upstream_srv_conf(uscfp[i], + ngx_http_upstream_keepalive_module); + + if (kcf->max_cached == 0) { + continue; + } + + ngx_conf_init_msec_value(kcf->time, 3600000); + ngx_conf_init_msec_value(kcf->timeout, 60000); + ngx_conf_init_uint_value(kcf->requests, 1000); + + if (kcf->max_cached == NGX_CONF_UNSET_UINT) { + kcf->local = 1; + kcf->max_cached = 32; + } + + kcf->original_init_peer = uscfp[i]->peer.init; + + uscfp[i]->peer.init = ngx_http_upstream_init_keepalive_peer; + + /* allocate cache items and add to free queue */ + + cached = ngx_pcalloc(cf->pool, + sizeof(ngx_http_upstream_keepalive_cache_t) * kcf->max_cached); + if (cached == NULL) { + return NGX_CONF_ERROR; + } + + ngx_queue_init(&kcf->cache); + ngx_queue_init(&kcf->free); + + for (j = 0; j < kcf->max_cached; j++) { + ngx_queue_insert_head(&kcf->free, &cached[j].queue); + cached[j].conf = kcf; + } + } + + return NGX_CONF_OK; +} + + +static char * ngx_http_upstream_keepalive(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { - ngx_http_upstream_srv_conf_t *uscf; ngx_http_upstream_keepalive_srv_conf_t *kcf = conf; ngx_int_t n; ngx_str_t *value; - if (kcf->max_cached) { + if (kcf->max_cached != NGX_CONF_UNSET_UINT) { return "is duplicate"; } @@ -573,7 +597,7 @@ n = ngx_atoi(value[1].data, value[1].len); - if (n == NGX_ERROR || n == 0) { + if (n == NGX_ERROR) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid value \"%V\" in \"%V\" directive", &value[1], &cmd->name); @@ -582,15 +606,16 @@ kcf->max_cached = n; - /* init upstream handler */ - - uscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_upstream_module); - - kcf->original_init_upstream = uscf->peer.init_upstream - ? uscf->peer.init_upstream - : ngx_http_upstream_init_round_robin; - - uscf->peer.init_upstream = ngx_http_upstream_init_keepalive; + if (cf->args->nelts == 3) { + if (ngx_strcmp(value[2].data, "local") == 0) { + kcf->local = 1; + + } else { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid parameter \"%V\"", &value[2]); + return NGX_CONF_ERROR; + } + } return NGX_CONF_OK; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.6/src/http/ngx_http.c new/nginx-1.29.7/src/http/ngx_http.c --- old/nginx-1.29.6/src/http/ngx_http.c 2026-03-10 16:29:07.000000000 +0100 +++ new/nginx-1.29.7/src/http/ngx_http.c 2026-03-24 16:38:34.000000000 +0100 @@ -1846,6 +1846,7 @@ #endif ls->type = addr->opt.type; + ls->protocol = addr->opt.protocol; ls->backlog = addr->opt.backlog; ls->rcvbuf = addr->opt.rcvbuf; ls->sndbuf = addr->opt.sndbuf; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.6/src/http/ngx_http_core_module.c new/nginx-1.29.7/src/http/ngx_http_core_module.c --- old/nginx-1.29.6/src/http/ngx_http_core_module.c 2026-03-10 16:29:07.000000000 +0100 +++ new/nginx-1.29.7/src/http/ngx_http_core_module.c 2026-03-24 16:38:34.000000000 +0100 @@ -4223,6 +4223,19 @@ continue; } + if (ngx_strcmp(value[n].data, "multipath") == 0) { +#ifdef IPPROTO_MPTCP + lsopt.protocol = IPPROTO_MPTCP; + lsopt.set = 1; + lsopt.bind = 1; +#else + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "multipath is not supported " + "on this platform, ignored"); +#endif + continue; + } + if (ngx_strcmp(value[n].data, "ssl") == 0) { #if (NGX_HTTP_SSL) lsopt.ssl = 1; @@ -4389,6 +4402,12 @@ } #endif +#ifdef IPPROTO_MPTCP + if (lsopt.protocol == IPPROTO_MPTCP) { + return "\"multipath\" parameter is incompatible with \"quic\""; + } +#endif + #if (NGX_HTTP_SSL) if (lsopt.ssl) { return "\"ssl\" parameter is incompatible with \"quic\""; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.6/src/http/ngx_http_core_module.h new/nginx-1.29.7/src/http/ngx_http_core_module.h --- old/nginx-1.29.6/src/http/ngx_http_core_module.h 2026-03-10 16:29:07.000000000 +0100 +++ new/nginx-1.29.7/src/http/ngx_http_core_module.h 2026-03-24 16:38:34.000000000 +0100 @@ -88,6 +88,7 @@ int rcvbuf; int sndbuf; int type; + int protocol; #if (NGX_HAVE_SETFIB) int setfib; #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.6/src/http/ngx_http_header_filter_module.c new/nginx-1.29.7/src/http/ngx_http_header_filter_module.c --- old/nginx-1.29.6/src/http/ngx_http_header_filter_module.c 2026-03-10 16:29:07.000000000 +0100 +++ new/nginx-1.29.7/src/http/ngx_http_header_filter_module.c 2026-03-24 16:38:34.000000000 +0100 @@ -91,7 +91,7 @@ ngx_string("404 Not Found"), ngx_string("405 Not Allowed"), ngx_string("406 Not Acceptable"), - ngx_null_string, /* "407 Proxy Authentication Required" */ + ngx_string("407 Proxy Authentication Required"), ngx_string("408 Request Time-out"), ngx_string("409 Conflict"), ngx_string("410 Gone"), diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.6/src/http/ngx_http_request.c new/nginx-1.29.7/src/http/ngx_http_request.c --- old/nginx-1.29.6/src/http/ngx_http_request.c 2026-03-10 16:29:07.000000000 +0100 +++ new/nginx-1.29.7/src/http/ngx_http_request.c 2026-03-24 16:38:34.000000000 +0100 @@ -152,6 +152,10 @@ offsetof(ngx_http_headers_in_t, authorization), ngx_http_process_unique_header_line }, + { ngx_string("Proxy-Authorization"), + offsetof(ngx_http_headers_in_t, proxy_authorization), + ngx_http_process_unique_header_line }, + { ngx_string("Keep-Alive"), offsetof(ngx_http_headers_in_t, keep_alive), ngx_http_process_header_line }, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.6/src/http/ngx_http_request.h new/nginx-1.29.7/src/http/ngx_http_request.h --- old/nginx-1.29.6/src/http/ngx_http_request.h 2026-03-10 16:29:07.000000000 +0100 +++ new/nginx-1.29.7/src/http/ngx_http_request.h 2026-03-24 16:38:34.000000000 +0100 @@ -95,6 +95,7 @@ #define NGX_HTTP_FORBIDDEN 403 #define NGX_HTTP_NOT_FOUND 404 #define NGX_HTTP_NOT_ALLOWED 405 +#define NGX_HTTP_PROXY_AUTH_REQUIRED 407 #define NGX_HTTP_REQUEST_TIME_OUT 408 #define NGX_HTTP_CONFLICT 409 #define NGX_HTTP_LENGTH_REQUIRED 411 @@ -210,6 +211,7 @@ #endif ngx_table_elt_t *authorization; + ngx_table_elt_t *proxy_authorization; ngx_table_elt_t *keep_alive; @@ -273,6 +275,7 @@ ngx_table_elt_t *content_range; ngx_table_elt_t *accept_ranges; ngx_table_elt_t *www_authenticate; + ngx_table_elt_t *proxy_authenticate; ngx_table_elt_t *expires; ngx_table_elt_t *etag; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.6/src/http/ngx_http_special_response.c new/nginx-1.29.7/src/http/ngx_http_special_response.c --- old/nginx-1.29.6/src/http/ngx_http_special_response.c 2026-03-10 16:29:07.000000000 +0100 +++ new/nginx-1.29.7/src/http/ngx_http_special_response.c 2026-03-24 16:38:34.000000000 +0100 @@ -153,6 +153,14 @@ ; +static char ngx_http_error_407_page[] = +"<html>" CRLF +"<head><title>407 Proxy Authentication Required</title></head>" CRLF +"<body>" CRLF +"<center><h1>407 Proxy Authentication Required</h1></center>" CRLF +; + + static char ngx_http_error_408_page[] = "<html>" CRLF "<head><title>408 Request Time-out</title></head>" CRLF @@ -364,7 +372,7 @@ ngx_string(ngx_http_error_404_page), ngx_string(ngx_http_error_405_page), ngx_string(ngx_http_error_406_page), - ngx_null_string, /* 407 */ + ngx_string(ngx_http_error_407_page), ngx_string(ngx_http_error_408_page), ngx_string(ngx_http_error_409_page), ngx_string(ngx_http_error_410_page), diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.6/src/mail/ngx_mail.c new/nginx-1.29.7/src/mail/ngx_mail.c --- old/nginx-1.29.6/src/mail/ngx_mail.c 2026-03-10 16:29:07.000000000 +0100 +++ new/nginx-1.29.7/src/mail/ngx_mail.c 2026-03-24 16:38:34.000000000 +0100 @@ -332,6 +332,7 @@ ls->log.data = &ls->addr_text; ls->log.handler = ngx_accept_log_error; + ls->protocol = addr[i].opt.protocol; ls->backlog = addr[i].opt.backlog; ls->rcvbuf = addr[i].opt.rcvbuf; ls->sndbuf = addr[i].opt.sndbuf; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.6/src/mail/ngx_mail.h new/nginx-1.29.7/src/mail/ngx_mail.h --- old/nginx-1.29.6/src/mail/ngx_mail.h 2026-03-10 16:29:07.000000000 +0100 +++ new/nginx-1.29.7/src/mail/ngx_mail.h 2026-03-24 16:38:34.000000000 +0100 @@ -47,6 +47,7 @@ int tcp_keepintvl; int tcp_keepcnt; #endif + int protocol; int backlog; int rcvbuf; int sndbuf; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.6/src/mail/ngx_mail_auth_http_module.c new/nginx-1.29.7/src/mail/ngx_mail_auth_http_module.c --- old/nginx-1.29.6/src/mail/ngx_mail_auth_http_module.c 2026-03-10 16:29:07.000000000 +0100 +++ new/nginx-1.29.7/src/mail/ngx_mail_auth_http_module.c 2026-03-24 16:38:34.000000000 +0100 @@ -1328,7 +1328,7 @@ b->last = ngx_cpymem(b->last, "Auth-Salt: ", sizeof("Auth-Salt: ") - 1); b->last = ngx_copy(b->last, s->salt.data, s->salt.len); - s->passwd.data = NULL; + ngx_str_null(&s->passwd); } b->last = ngx_cpymem(b->last, "Auth-Protocol: ", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.6/src/mail/ngx_mail_core_module.c new/nginx-1.29.7/src/mail/ngx_mail_core_module.c --- old/nginx-1.29.6/src/mail/ngx_mail_core_module.c 2026-03-10 16:29:07.000000000 +0100 +++ new/nginx-1.29.7/src/mail/ngx_mail_core_module.c 2026-03-24 16:38:34.000000000 +0100 @@ -447,6 +447,18 @@ #endif } + if (ngx_strcmp(value[i].data, "multipath") == 0) { +#ifdef IPPROTO_MPTCP + ls->protocol = IPPROTO_MPTCP; + ls->bind = 1; +#else + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "multipath is not supported " + "on this platform, ignored"); +#endif + continue; + } + if (ngx_strcmp(value[i].data, "ssl") == 0) { #if (NGX_MAIL_SSL) ngx_mail_ssl_conf_t *sslcf; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.6/src/mail/ngx_mail_smtp_handler.c new/nginx-1.29.7/src/mail/ngx_mail_smtp_handler.c --- old/nginx-1.29.6/src/mail/ngx_mail_smtp_handler.c 2026-03-10 16:29:07.000000000 +0100 +++ new/nginx-1.29.7/src/mail/ngx_mail_smtp_handler.c 2026-03-24 16:38:34.000000000 +0100 @@ -13,6 +13,7 @@ static void ngx_mail_smtp_resolve_addr_handler(ngx_resolver_ctx_t *ctx); +static ngx_int_t ngx_mail_smtp_validate_host(ngx_str_t *name); static void ngx_mail_smtp_resolve_name(ngx_event_t *rev); static void ngx_mail_smtp_resolve_name_handler(ngx_resolver_ctx_t *ctx); static void ngx_mail_smtp_block_reading(ngx_event_t *rev); @@ -127,6 +128,20 @@ return; } + if (ngx_mail_smtp_validate_host(&ctx->name) != NGX_OK) { + ngx_log_error(NGX_LOG_ERR, c->log, 0, + "%V resolved to invalid host name \"%V\"", + &c->addr_text, &ctx->name); + + s->host = smtp_tempunavail; + + ngx_resolve_addr_done(ctx); + + ngx_mail_smtp_greeting(s, s->connection); + + return; + } + c->log->action = "in resolving client hostname"; s->host.data = ngx_pstrdup(c->pool, &ctx->name); @@ -149,6 +164,36 @@ } +static ngx_int_t +ngx_mail_smtp_validate_host(ngx_str_t *name) +{ + u_char ch; + ngx_uint_t i; + + if (name->len == 0) { + return NGX_DECLINED; + } + + for (i = 0; i < name->len; i++) { + ch = name->data[i]; + + /* allow only characters from RFC 1034, Section 3.5 */ + + if ((ch >= 'a' && ch <= 'z') + || (ch >= 'A' && ch <= 'Z') + || (ch >= '0' && ch <= '9') + || ch == '-' || ch == '.') + { + continue; + } + + return NGX_DECLINED; + } + + return NGX_OK; +} + + static void ngx_mail_smtp_resolve_name(ngx_event_t *rev) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.6/src/stream/ngx_stream.c new/nginx-1.29.7/src/stream/ngx_stream.c --- old/nginx-1.29.6/src/stream/ngx_stream.c 2026-03-10 16:29:07.000000000 +0100 +++ new/nginx-1.29.7/src/stream/ngx_stream.c 2026-03-24 16:38:34.000000000 +0100 @@ -1010,6 +1010,7 @@ ls->log.handler = ngx_accept_log_error; ls->type = addr->opt.type; + ls->protocol = addr->opt.protocol; ls->backlog = addr->opt.backlog; ls->rcvbuf = addr->opt.rcvbuf; ls->sndbuf = addr->opt.sndbuf; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.6/src/stream/ngx_stream.h new/nginx-1.29.7/src/stream/ngx_stream.h --- old/nginx-1.29.6/src/stream/ngx_stream.h 2026-03-10 16:29:07.000000000 +0100 +++ new/nginx-1.29.7/src/stream/ngx_stream.h 2026-03-24 16:38:34.000000000 +0100 @@ -62,6 +62,7 @@ int rcvbuf; int sndbuf; int type; + int protocol; #if (NGX_HAVE_SETFIB) int setfib; #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.6/src/stream/ngx_stream_core_module.c new/nginx-1.29.7/src/stream/ngx_stream_core_module.c --- old/nginx-1.29.6/src/stream/ngx_stream_core_module.c 2026-03-10 16:29:07.000000000 +0100 +++ new/nginx-1.29.7/src/stream/ngx_stream_core_module.c 2026-03-24 16:38:34.000000000 +0100 @@ -1202,6 +1202,19 @@ continue; } + if (ngx_strcmp(value[i].data, "multipath") == 0) { +#ifdef IPPROTO_MPTCP + lsopt.protocol = IPPROTO_MPTCP; + lsopt.set = 1; + lsopt.bind = 1; +#else + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "multipath is not supported " + "on this platform, ignored"); +#endif + continue; + } + if (ngx_strcmp(value[i].data, "ssl") == 0) { #if (NGX_STREAM_SSL) lsopt.ssl = 1; @@ -1338,6 +1351,12 @@ } #endif +#ifdef IPPROTO_MPTCP + if (lsopt.protocol == IPPROTO_MPTCP) { + return "\"multipath\" parameter is incompatible with \"udp\""; + } +#endif + #if (NGX_STREAM_SSL) if (lsopt.ssl) { return "\"ssl\" parameter is incompatible with \"udp\""; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.6/src/stream/ngx_stream_ssl_module.c new/nginx-1.29.7/src/stream/ngx_stream_ssl_module.c --- old/nginx-1.29.6/src/stream/ngx_stream_ssl_module.c 2026-03-10 16:29:07.000000000 +0100 +++ new/nginx-1.29.7/src/stream/ngx_stream_ssl_module.c 2026-03-24 16:38:34.000000000 +0100 @@ -437,6 +437,7 @@ long rc; X509 *cert; ngx_int_t rv; + const char *str; ngx_connection_t *c; ngx_stream_ssl_srv_conf_t *sscf; @@ -487,6 +488,15 @@ X509_free(cert); } + + if (ngx_ssl_ocsp_get_status(c, &str) != NGX_OK) { + ngx_log_error(NGX_LOG_INFO, c->log, 0, + "client SSL certificate verify error: %s", str); + + ngx_ssl_remove_cached_session(c->ssl->session_ctx, + (SSL_get0_session(c->ssl->connection))); + return NGX_ERROR; + } } return NGX_OK; ++++++ nginx.keyring ++++++ --- /var/tmp/diff_new_pack.ZUgxr5/_old 2026-03-27 06:45:18.443577582 +0100 +++ /var/tmp/diff_new_pack.ZUgxr5/_new 2026-03-27 06:45:18.451577913 +0100 @@ -1,66 +1,115 @@ -----BEGIN PGP PUBLIC KEY BLOCK----- -mQINBGKE4psBEADpHSM/IxFD1nXBmnODYXzcl2A+6b6m9m1m2Y4Dlr0ed+y5Lxne -QidE9I74A2KSm6+eHW2yh4i1ZwZbmwpmQqM+j5BMt7axoXOdKSyN+fYtUakzNbBN -EDRKT79q/zIzkgTJradHkCQkwF1W3go+qPXjR2ZEnLma9dZED9VNI6PmOpeYaASo -IkEfbKbwa/vPrvnDSSYY6Y02RXSRk5U1NvQgVUTJP9WGK7NlPUcTBDELLQv6fFPU -kjBOel6MecsQ+v8iq4RJF2cbVF0hNjbAiNldjLV74Xd7yWVRlCbdb2agyvQjMNrD -jHSvbEMiNB3R8yBHVW2Zldv8q0XjcwoDfdiZYFJe3lRUYmv6I2p+/DptD4r/3ILI -peGZtSeOdQEw+vvODL/Ehq03anTrzcpZ6sDLfLrYJhYcrltj0/LMUnLDAjciwRUq -XI46EfxwqsdLeqoZFQeO3LOFsh0kJKR2xOrUHIVy84NJ4Gmro6WmUkb1NfdjyHzF -z8Lfbo46NKoTcwFsFF0q74jVVIVNUyIS91DusiMqLCsP8jqDOz/kyP4bOJQ+aUXf -BANn4Ll1TFWsJ417moxz+Pi5sTaI0na8z2XB1N9WPsSml3FS75hJPJshN2T3VIea -zB7GFWqk33ynSDt+cAisG5nsK9fFdcH+t5wm59oobyFbFhKxwX6ROuxlZwARAQAB -tCRTZXJnZXkgS2FuZGF1cm92IDxwbHVrbmV0QG5naW54LmNvbT6JAk4EEwEKADgW -IQTWeGzjA9mpAimY3GzIRk1UmvdcCgUCYoTimwIbAwULCQgHAwUVCgkICwUWAwIB -AAIeAQIXgAAKCRDIRk1UmvdcCqbOD/9Htgk3mWvUFmrApkWQTIDNmLACZ1Sw1PXj -Uqte8StYB0bYY+nmAXs7O5eC2h1ViParl7En1joEEMQQmH0qSnw4X1CM/hA8TAYW -mBPITTNWo/R52WoyWeWGFnFNIperQmuIZc+pXm0VEFVPiX/2DXbCIu+jaXySvlCN -LekmOD4VC7dJS8/ohoaXOR2T8ufS+1CsyPXomEb+COhqRZ3EVBa+k7pnElkFft3Y -a1fR0AgatZFQpy+ukePhK7s/M5RGhDJWHgSAZFkf+X2jVV4NRJ+XsY80gU5DD2ZX -QT6Je6Knxqk7FnWNSxkhReH6Ss5flZSoGDCmJ2AsPtGeUhus2fGqeN+waGKTZC35 -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 -x0VGHDmuaYQ= -=HmVo +mQINBGYXyiQBEAC4jm1y+ODV4+YDGj9vp2BgHB4FJeQdgrBiVX+Mb2qCrEqJgeKV +fVwKjkVYqnb76TTybdOKqCP5wdQrncKAKlXsMq6sdsiwPSrdRcjkeiE29WWrtbB4 +i+VObnoWklMblMxFQ1XQIkjs2wviidKjJw2VV3i4XnLSrHhWaWqviTLZCMQymoPs +F+Tfu1WX9OUfOquekZ5KjkyBxB4ep6+NPeuIkPnW0SiTUhU8tbi8v0aBZEHSZLqE +mq8KLROVuYSPvtU+NtaXAM09BHEVCfb409aDps9p6AFT+IN8yoOegGdEZjp6hJvS +HxbhuwqNEtg4dTEV515YUCgKabqU1QaqI/Y0+Pdkpep1KRFc9YUYttDkCw7Ybu2u +fwTGzwAbD+ThAIOdzmMDodzZaEMf+9fQG4bnO1PdNbXzyP7Kv9qzGa65+9oGCPOS +qTpISR8pvzoI8w/Z/vG71ob/nQ6Xm0L986ksErdGhu16ZI7lW2eDYqy2IoFfbeSz +HHxk484/pEibrlCRbP2Id+zULfxo1HGOGg+PAY9Q2uNzABsGDMnOhIvXHS+hP7oB +sO9A4Prqu6K6cMp3QI219tmmOUegJpmGGPzoNgxR7H30wNcjZPv4PWr/c0fP70Ny +ilgbdcEMDSHks30AmiuIvcUxo3A21p2nnpxsKAKYx42UJkyEK0HILMzcqwARAQAB +tCZSb21hbiBBcnV0eXVueWFuIDxyLmFydXR5dW55YW5AZjUuY29tPokCTgQTAQgA +OBYhBEM4eCXdsbuX7Da6XQB8jXwV2HNpBQJmF8pXAhsDBQsJCAcCBhUKCQgLAgQW +AgMBAh4BAheAAAoJEAB8jXwV2HNppvQP/AjzdPKkGRzJkb1ioto/IEP1YhA/Eayk +hvejJ0vyWVHXXH7FLW9fIZoApcsD1J8/7zIANm+62IfT3QNbL2R44IyhJB3AY22l +t0ToLxodfugegF3NPYYyFOSRUoPD4g2T/dMCPOBX4MNEAnAlCmxAMaJNmQUO76IY +GwELa3CH3Aqf7bthKy8P36G11hu7NgH6V9mVIRIpfnfpXFQIztj+vsWtswu4M5t7 +BNJwx4a2KTCVQpTdff5/0dO/5drQDxLbIg681WZk3Oe8Eu6nSc0Ud02NIkg1TQH/ +MryAp7o/ua3LRem+W/cktnT60p4uXPVZ3Rvg3zOmJSNJ+eIXY2+sDeZEPaROKldA +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 +kZv2zEcTtzlAYNEumy8KrJzICmPLS7BEC8w= +=ilJ3 -----END PGP PUBLIC KEY BLOCK-----
