]> git.kaiwu.me - nginx.git/log
nginx.git
3 weeks agoMisc: fixed "zip" target with GNU sed stable-1.30
Sergey Kandaurov [Mon, 19 Oct 2026 19:17:59 +0000 (19:17 +0000)]
Misc: fixed "zip" target with GNU sed

3 weeks agoGH: request an id token and pass secrets to a callee in buildbot.yml
Konstantin Pavlov [Mon, 28 Sep 2026 21:13:07 +0000 (14:13 -0700)]
GH: request an id token and pass secrets to a callee in buildbot.yml

Both are required to be able to do authentication in a callee workflow.

3 weeks agoGH: workflow to generate windows zip
Sai Krishna Kumar Reddy YADAMAKANTI [Wed, 30 Sep 2026 13:12:44 +0000 (13:12 +0000)]
GH: workflow to generate windows zip

3 weeks agoGH: explicitly set permissions in workflows
Andrew Clayton [Wed, 10 Jun 2026 04:52:46 +0000 (05:52 +0100)]
GH: explicitly set permissions in workflows

These will override the default repo/org GITHUB_TOKEN scope.

3 weeks agoVersion bump
Sergey Kandaurov [Tue, 20 Oct 2026 15:26:22 +0000 (19:26 +0400)]
Version bump

5 weeks agonginx-1.30.6-RELEASE release-1.30.6
Sergey Kandaurov [Thu, 1 Oct 2026 19:36:05 +0000 (23:36 +0400)]
nginx-1.30.6-RELEASE

5 weeks agoAvoid post-rewrite URI to path mapping with alias
Roman Arutyunyan [Fri, 10 Jul 2026 16:10:12 +0000 (20:10 +0400)]
Avoid post-rewrite URI to path mapping with alias

Previously, after a "rewrite" had changed the URI, and before a new
location was chosen, the new URI might not match the current location
prefix.  This becomes a problem when the location uses "alias", which
is why normally such inconsistency is detected by checking the
r->valid_location flag.  Meanwhile this flag only handles the
inconsistency when using the "break" directive or parameter.  However
in absence of those, there's still an inconsistency window from URI
change up until the end of the current set of rewrite directives.
URI to path mapping within this window might result in a buffer
overflow if location's prefix was longer than the rewritten URI.

The following example resulted in a buffer overflow with the request
"/foo/1":

location /foo/ {
    alias /bar/;
    rewrite ^/foo/.*$ /x;
    return 200 $request_filename;
}

Alternatively, $request_filename might be used in access log format,
"set", "if", "add_header", etc.

The fix is to reject URI mapping in ngx_http_map_uri_to_path() if the
r->uri_changed flag is set.

5 weeks agoScript: reserved memory overrun protection in ngx_http_script_run()
Roman Arutyunyan [Wed, 29 Jul 2026 12:57:59 +0000 (16:57 +0400)]
Script: reserved memory overrun protection in ngx_http_script_run()

In b76754049 buffer overrun protection in script was introduced.
However in ngx_http_script_run() data could still spill over to the
reserved area.  This had no visible effects except the return value
which could extend beyond the maximum formatted string size.  This
value is however currently unused in the nginx code.

Later in a8289aa69 string length recalculation was implemented to
protect against buffer underwrite.  Considering a possible spillover to
the reserved area, the final string size could become larger than the
allocated buffer size.  This could later result in writing beyond
the buffer boundaries.  Maximum buffer overflow is the size of the
reserved area.

This could affect calculating document root from variables in HTTP
or using access logging in HTTP or Stream.  In the case of access
logging a possible impact is limited by an off-by-one write of a null
byte.

Reported by Matt Suiche of Tolmo Inc.

5 weeks agoSSL: synced all session ticket keys to the worker process
Vadim Zhestikov [Wed, 22 Jul 2026 23:48:37 +0000 (16:48 -0700)]
SSL: synced all session ticket keys to the worker process

The per-worker ticket key mirror is allocated with three slots
(ngx_array_push_n(keys, 3)), matching the shared memory
ticket_keys[3] array and the decrypt callback, which scans all
keys->nelts slots by key name.  Key rotation, however, synced
only two slots from shared memory, leaving the third slot's
name, hmac_key, and aes_key uninitialized.

A ticket whose key name matched the uninitialized slot (which
holds unspecified pool memory, all zero in the best case) could
therefore be HMAC-verified and decrypted with uninitialized key
material, allowing a forged session.

Sync all keys->nelts slots, as ngx_ssl_ticket_keys_cleanup()
already assumes.

Reported by PhiNode Labs.

5 weeks agoHTTP/3: kept the skipped frame length separate from data length
Vadim Zhestikov [Thu, 23 Jul 2026 00:48:55 +0000 (17:48 -0700)]
HTTP/3: kept the skipped frame length separate from data length

ngx_http_v3_parse_data() stored the remaining length of a skipped
(unknown) frame in st->length -- the same field the request body
filter uses for the number of DATA payload bytes to pass on as
request body.  When an unknown frame was split across parser
invocations, the skip was interrupted with st->length holding the
skip remainder; on the next buffer the body filter, which calls
the parser only while st->length == 0, treated that remainder as
request body.

When proxying, this could result in sending unframed bytes, potentially
allowing for bypass of client_max_body_size, which is enforced only on
the DATA path, or an injection.

The fix is to keep unknown frame payload in a separate st->skip counter.

Reported by Hansol Lee of GOTROOT.

5 weeks agoLimited the number of pending operations per request
Vadim Zhestikov [Mon, 17 Aug 2026 16:19:46 +0000 (09:19 -0700)]
Limited the number of pending operations per request

Each pending asynchronous operation holds a reference in
r->main->blocked, an 8-bit field, and the increments were not checked.
With 256 operations pending on a single request the counter wrapped to
zero, after which the request could be freed while those operations
still referenced its pool.  This is the same overflow that 4ec67cf86
addressed for r->main->count, and left unaddressed for r->main->blocked.

Operations beyond the limit are now performed synchronously where a
synchronous path exists, and refused otherwise, so that the counter
cannot overflow.

Reported by cyberlancer.

5 weeks agoUpstream: fixed X-Accel-Redirect handling from cache files.
Maxim Dounin [Mon, 19 Feb 2024 22:23:43 +0000 (01:23 +0300)]
Upstream: fixed X-Accel-Redirect handling from cache files.

The X-Accel-Redirect header might appear in cache files if its handling
is ignored with the "proxy_ignore_headers" directive.  If the cache file
is later served with different settings, ngx_http_upstream_process_headers()
used to call ngx_http_upstream_finalize_request(NGX_DECLINED), which
is not expected to happen before the cleanup handler is installed and
resulted in ngx_http_finalize_request(NGX_DONE) (after 2b032e8df,
nginx 1.7.11), leading to unexpected request counter decrement, "request
count is zero" alerts, and segmentation faults.

Similarly, errors in ngx_http_upstream_process_headers() resulted in
ngx_http_upstream_finalize_request(NGX_HTTP_INTERNAL_SERVER_ERROR) being
called.  This is also not expected to happen before the cleanup handler is
installed, and resulted in ngx_http_finalize_request(NGX_DONE) without
proper request finalization.

Fix is to avoid calling ngx_http_upstream_finalize_request() from
ngx_http_upstream_process_headers(), notably when the cleanup handler
is not yet installed.  Errors are now simply return NGX_ERROR, so the
caller is responsible for proper finalization by calling either
ngx_http_finalize_request() or ngx_http_upstream_finalize_request().
And X-Accel-Redirect handling now does not call
ngx_http_upstream_finalize_request(NGX_DECLINED) if no cleanup handler
is installed.

Reported by Jiří Setnička
(https://mailman.nginx.org/pipermail/nginx-devel/2024-February/HWLYHOO3DDB3XTFT6X3GRMXIEJ3SJRUA.html).

5 weeks agoUpdated OpenSSL and PCRE used for win32 builds
Sergey Kandaurov [Wed, 30 Sep 2026 13:23:05 +0000 (17:23 +0400)]
Updated OpenSSL and PCRE used for win32 builds

5 weeks agoDav: destination validation for COPY and MOVE with "alias".
Maxim Dounin [Fri, 11 Sep 2026 15:18:36 +0000 (08:18 -0700)]
Dav: destination validation for COPY and MOVE with "alias".

If COPY or MOVE methods are enabled, the DAV module assumes that it is
configured for the whole server, and does not try validate that the
destination URI is within the particular location.  This, however, does
not work well if it is in fact configured in a non-root location, and
this location uses the "alias" directive, such as in the following
configuration:

    location /prefix/ {
        dav_methods COPY;
        alias /foo/;
    }

In particular, if the destination URI is shorter than the aliased
location prefix, calling ngx_http_map_uri_to_path() with such
destination URI used to result in segmentation faults (9739e755b).  And
if the destination URI is longer than the aliased location prefix, but
does not match it, calling ngx_http_map_uri_to_path() resulted in
unexpected path values, including ones above the "alias" directory
specified.

The fix is to check destination URI prefix if "alias" is used, similarly
to what we do with "try_files".  Additionally, the
ngx_http_map_uri_to_path() function was updated with additional sanity
checking to prevent similar issues.

This change is a modified version of a patch by Maxim Dounin.  The
modifications include skipping the prefix check if the URI was
rewritten, which preserves the "alias" diagnostics of
ngx_http_map_uri_to_path().

Signed-off-by: Vadim Zhestikov <v.zhestikov@f5.com>
Origin: <https://freenginx.org/hg/nginx/rev/aae28b083279>

5 weeks agoGeo: check binary base CRC32 before relocation
Sergey Kandaurov [Mon, 7 Sep 2026 15:47:51 +0000 (19:47 +0400)]
Geo: check binary base CRC32 before relocation

This provides safe pointer handling in the event of a corrupted file.

5 weeks agoEvent pipe: do not free buffers still used by the downstream
Ivan Ovchinnikov [Fri, 21 Aug 2026 20:48:15 +0000 (20:48 +0000)]
Event pipe: do not free buffers still used by the downstream

When a body filter returned an error, ngx_event_pipe_drain_chains()
returned all buffers to p->free_raw_bufs, including those in p->busy,
which are still owned by the downstream. If upstream EOF was detected
in the same ngx_event_pipe() pass, ngx_event_pipe_read_upstream() then
freed them while still referenced. With HTTP/2 only the stream's fake
connection is marked on error, so ngx_http_v2_send_output_queue() kept
sending DATA frames pointing at the freed buffers, a use-after-free.

Fixed by keeping the p->busy chains intact, the buffers are freed with
the request pool.  This also stops the pipe from reusing them for new
upstream reads, which previously could overwrite response body data
still queued for the client.  Additionally, the pipe no longer treats
a downstream it has given up on as merely blocked, so the loop is
still guaranteed to terminate.

Co-authored-by: Roman Arutyunyan <arut@nginx.com>
5 weeks agoSlice filter: overflow protection in slice range requests
Vadim Zhestikov [Tue, 11 Aug 2026 21:06:19 +0000 (14:06 -0700)]
Slice filter: overflow protection in slice range requests

When the byte range is passed in the client Range header, the range
start is accepted up to NGX_MAX_OFF_T_VALUE, while
ngx_http_slice_range_variable() adds the slice size to it when
formatting the slice end.  With start values close to the maximum
this overflowed.

Now such range starts are ignored, similarly to other ranges not
handled by ngx_http_slice_get_start().

5 weeks agoQUIC: rejected CRYPTO frames received in 1-RTT packets
Vadim Zhestikov [Wed, 12 Aug 2026 19:41:54 +0000 (12:41 -0700)]
QUIC: rejected CRYPTO frames received in 1-RTT packets

If a CRYPTO frame was received after the handshake, ngx_quic_handshake()
ran the handshake completion for the second time.  With the check added
in 6f8c520f4, this is limited to short header packets.

Since a client has nothing to send in a CRYPTO frame once the handshake
is complete, such frames are now rejected with the "unexpected_message"
connection error, as does TLS 1.3 for handshake messages received out of
order, and QUIC requires for KeyUpdate.

5 weeks agoMemcached: respect the end marker in the maximum supported length
Vadim Zhestikov [Tue, 11 Aug 2026 18:06:28 +0000 (11:06 -0700)]
Memcached: respect the end marker in the maximum supported length

The length in the "VALUE" line was accepted up to NGX_MAX_OFF_T_VALUE,
while ngx_http_memcached_filter_init() adds the size of the end marker
to it.  With lengths close to the maximum this overflowed u->length.

Now such lengths are rejected, similarly to other invalid lengths.

5 weeks agoCore: delete accept timer on worker shutdown
Roman Arutyunyan [Thu, 20 Aug 2026 12:53:42 +0000 (16:53 +0400)]
Core: delete accept timer on worker shutdown

Previously, when the worker file descriptor table was full, a listen
connection might be disabled and a timeout might be set for re-enabling
it.  If during this period the worker received the NGX_CMD_QUIT signal,
the accept connection would be recycled, but the timer would remain set.
On timer expiration, an attempt to accept a new connection would result
in "accept4() failed (9: Bad file descriptor)" alert because c->fd was
reset to -1.

Fix is to delete accept timer when closing listen connections.

5 weeks agoCore: make channel file descriptor errors non-fatal
Roman Arutyunyan [Tue, 18 Aug 2026 16:58:42 +0000 (20:58 +0400)]
Core: make channel file descriptor errors non-fatal

If a worker process' file descriptor table is full, recvmsg() is not
able to read out the channel fd sent from the master.  This results in
different behavior on different platforms.

On Linux, recvmsg() succeeds, returns the payload and drops the fd.
On BSD systems, the first recvmsg() call fails with EMSGSIZE/EMFILE,
but the next call succeeds and returns the payload without the fd.
On Solaris, recvmsg() fails with EMFILE and drops both the payload
and the fd.

Previously, all of these paths resulted in fatal errors.  The worker
channel was closed and the worker was no longer capable of receiving
messages from the master.  In particular, the NGX_CMD_QUIT command
could not be delivered anymore.  As a result, the worker never exited
after nginx reload and kept running and accepting new connections
forever until killed by a signal.

Fix is to consider those errors non-fatal.  An additional check is
added to the NGX_CMD_CLOSE_CHANNEL handler to make sure the worker
has received a file descriptor for this entry before. Also, the
MSG_CTRUNC check is removed since a proper ancillary data size
validation is now implemented.

5 weeks agoFixed overflow detection in chunked parser
Sergey Kandaurov [Thu, 6 Aug 2026 17:14:27 +0000 (21:14 +0400)]
Fixed overflow detection in chunked parser

This was broken in f405ef11f (1.29.4).

Reported by Matt Suiche, Tolmo Inc.

5 weeks agoScript: improved compatibility of complex value codes
Aleksei Bavshin [Thu, 16 Jul 2026 15:53:21 +0000 (08:53 -0700)]
Script: improved compatibility of complex value codes

In a8289aa69c74, we introduced a new code to finalize the evaluation of
a complex value, deferring the stack update to this new code.  However,
the change inadvertently broke compatibility with several third-party
modules that were reusing ngx_http_script_complex_value_code.

This change relegates omitted ngx_http_script_complex_value_end_code
from crash to a potential read of uninitialized bytes at the end of the
allocated buffer.

5 weeks agoPerl: fixed $r->print() zero copy with mutable scalars
David Carlier [Tue, 21 Jul 2026 03:35:57 +0000 (04:35 +0100)]
Perl: fixed $r->print() zero copy with mutable scalars

Since d9b7669666c8, the single-SV zero copy path in $r->print() no
longer required the SV to be read-only.  Reference counting introduced
by that change keeps the SV alive, but not its string buffer: modifying
a mutable scalar after $r->print() overwrites the buffer in place or
reallocates it, while nginx might still have it queued in r->out, since
small responses are postponed by ngx_http_write_filter().  This resulted
in corrupted responses, and in freed memory being sent to the client
when the scalar was grown.

The SV is now required to be read-only again.  Reference counting is
still needed here, as a read-only SV in an eval() might be freed with
the eval's op tree.

5 weeks agoEvents: validate descriptor before FD_SET()
Sourav Bhowmik [Wed, 22 Jul 2026 16:12:28 +0000 (09:12 -0700)]
Events: validate descriptor before FD_SET()

The check in ngx_select_init_conf() can be insufficient because it
doesn't cover descriptors for local files, which are not accounted
for in cycle->connection_n.  For instance, to reach this condition
with new connections, no reusable connections must be available for
recycling in ngx_get_connection().

The fix adopts a similar code from the win32 select module.

5 weeks agoImage filter: fixed reading past the received data
Vadim Zhestikov [Fri, 17 Jul 2026 20:16:08 +0000 (13:16 -0700)]
Image filter: fixed reading past the received data

The size parser and the image decoders used ctx->length, which is the
allocation size (set to image_filter_buffer when the upstream response
omits Content-Length), as the amount of valid data, so a truncated
response without Content-Length could be parsed or decoded past the
received bytes into uninitialized buffer memory.

The length is now adjusted to the actually-read size once the response
body has been read.

Reported by dukesp69 and YLChen-007.

5 weeks agoXslt: xmlCreatePushParserCtxt() error handling
Vadim Zhestikov [Thu, 16 Jul 2026 00:45:35 +0000 (17:45 -0700)]
Xslt: xmlCreatePushParserCtxt() error handling

On parser allocation failure, context was left uninitialized
resulting in null pointer dereference.

5 weeks agoConfigure: include crypt.h for crypt() feature tests
Aleksei Bavshin [Mon, 13 Jul 2026 22:12:47 +0000 (15:12 -0700)]
Configure: include crypt.h for crypt() feature tests

5 weeks agoPerl: request object validation
Maxim Dounin [Mon, 6 Jul 2026 04:14:28 +0000 (07:14 +0300)]
Perl: request object validation

Previously, using stale request objects resulted in accesses to already
freed memory, causing segmentation faults:

    location /stale {
        perl 'sub {
            my $r = shift;
            $prev->log_error(0, "next request arrived") if $prev;
            $prev = $r;
            $r->send_http_header;
            return OK;
        }';
    }

Similarly, incorrectly blessed objects might cause segmentation faults,
such as in the following configuration:

    location /bless {
        perl 'sub {
            my $v = 10;
            my $r = bless \$v, "nginx";
            $r->send_http_header;
            return OK;
        }';
    }

With this change, active request object is recorded in the
ngx_http_perl_call_handler() function, and checked by
ngx_http_perl_set_request() to prevent use of unexpected request
objects.

Reported by Axel Mierczuk, Keith Hoodlet, 1Password’s Off-by-1 Labs.

Signed-off-by: Sergey Kandaurov <pluknet@nginx.com>
Origin: https://freenginx.org/hg/nginx/rev/86a2685756ae

5 weeks agoPerl: introduced reference counting for perl scalars
Maxim Dounin [Fri, 26 Jun 2026 19:23:28 +0000 (22:23 +0300)]
Perl: introduced reference counting for perl scalars

Perl scalars might have a limited lifetime, and using them without
appropriate reference counting is incorrect.  In particular, heap
use-after-free was observed in the following configuration (note the
"eval", which limits lifetime of the string being printed), which
demonstrates that the previously used SvREADONLY() optimizations are
incorrect:

    location / {
        perl 'sub {
            my $r = shift;
            $r->send_http_header;
            eval q!$r->print("it works")!;
            return OK;
        }';
    }

Similarly, errors were observed with handlers in $r->sleep() and
$r->has_request_body() when a handler comes from an eval, such as in
the following configuration:

    location / {
        perl 'sub {
            my $r = shift;
            $r->sleep(100, eval q!sub {
                my $r = shift;
                $r->send_http_header;
                $r->print("it works");
                return OK;
            }!);
            return OK;
        }';
    }

Accordingly, the SvREADONLY() optimization was removed in
ngx_http_perl_sv2str(), since it is expected to be used for small
strings, and using proper reference counting likely will be more costly
than just copying the string.  In $r->print(), $r->sleep(), and
$r->has_request_body() proper reference counting was implemented, with
decrement operations being performed by pool cleanup handlers.

As a positive side effect, $r->print() can now avoid copying any single
scalar, not just read-only scalars.

Reported by Evan Hellman,
https://github.com/freenginx/nginx/issues/26

Signed-off-by: Sergey Kandaurov <pluknet@nginx.com>
Origin: https://freenginx.org/hg/nginx/rev/7a3dbb7905ad

5 weeks agoPerl: added handler type checks
Maxim Dounin [Fri, 26 Jun 2026 19:23:25 +0000 (22:23 +0300)]
Perl: added handler type checks

Previously, calling $r->sleep() and $r->has_request_body() with an
invalid handler argument, such as a string, resulted in a segmentation
fault.

Signed-off-by: Sergey Kandaurov <pluknet@nginx.com>
Origin: https://freenginx.org/hg/nginx/rev/2442b26850b1

5 weeks agoProxy: fixed HTTP/2 upstream with revalidated cache send
Zhidao HONG [Tue, 19 May 2026 07:59:56 +0000 (07:59 +0000)]
Proxy: fixed HTTP/2 upstream with revalidated cache send

Previously, a revalidated cached response could fail on a cached
keepalive connection with "upstream sent frame for unknown stream"
error followed by "cache file contains invalid header".

This happened because after a 304 response, nginx parsed the cached
response while the upstream peer connection was still attached to the
request.  The HTTP/2 proxy code treated cached frames as frames from
that live connection, and could assign a real stream id instead of
treating the cached response as having no real stream.

The fix is to treat cached response parsing as cache-only regardless
of the current upstream peer connection: set the stream id to 0 and
skip live upstream control-frame handling while r->cached is set.

Closes: https://github.com/nginx/nginx/issues/1318
5 weeks agoHTTP/2: fixed INITIAL_WINDOW_SIZE with saved state
Zhidao HONG [Mon, 1 Jun 2026 08:41:33 +0000 (08:41 +0000)]
HTTP/2: fixed INITIAL_WINDOW_SIZE with saved state

The window size change was previously kept in a local variable while
processing SETTINGS parameters.  If parsing was suspended after
SETTINGS_INITIAL_WINDOW_SIZE, the value was lost on resume and was
acknowledged without being applied.

Store the initial window size change in the HTTP/2 state until the
SETTINGS frame is fully processed.

5 weeks agoFix setting the IPV6_DONTFRAG socket option
Roman Arutyunyan [Wed, 8 Jul 2026 11:29:50 +0000 (15:29 +0400)]
Fix setting the IPV6_DONTFRAG socket option

The fix includes the socket option level (IPPROTO_IPV6) in the feature
test and the macro (NGX_HAVE_IPV6_DONTFRAG) in the
ngx_configure_listening_sockets() function.

Reported by Eric Fortis.

5 weeks agoCharset: disabled charset_map with utf-8 in the first column
Sergey Kandaurov [Thu, 2 Jul 2026 14:35:34 +0000 (18:35 +0400)]
Charset: disabled charset_map with utf-8 in the first column

This undocumented configuration was never expected to work and
resulted in immediate segfaults.

Reported by ret2ddme.

5 weeks agoAdd missing bounds check in ngx_{http,stream}_compile_complex_value()
Feng Wu [Tue, 23 Jun 2026 23:22:43 +0000 (07:22 +0800)]
Add missing bounds check in ngx_{http,stream}_compile_complex_value()

Complex value compilation scans strings for $1..$9 capture references.
Check that a byte after '$' is present before testing it, matching
ngx_str_t length semantics and avoiding reliance on NUL termination.

Apply the same check to both HTTP and stream implementations.

5 weeks agoAccess log: fix "request_length" format length
Nitin Swami [Fri, 5 Jun 2026 07:28:53 +0000 (12:58 +0530)]
Access log: fix "request_length" format length

The variable handler uses "%O" format specifier.

Reported by Mufeed VH of Winfunc Research.

5 weeks agoXslt: fix handling of vsnprintf() return value
Boris Tonofa [Fri, 20 Jun 2025 15:16:16 +0000 (18:16 +0300)]
Xslt: fix handling of vsnprintf() return value

5 weeks agoRewrite: harden escape flags control
Roman Arutyunyan [Thu, 14 May 2026 13:47:42 +0000 (17:47 +0400)]
Rewrite: harden escape flags control

Following 2046b45aa0c6, this change introduces better control of memory
allocation flags for escaped values.  Notably:

- The e->is_args flag is now explicitly reset on rewrite start.
  If the flag was set prior to rewrite start, then buffer overflow
  could happen before 2046b45aa0c6.

- The le->is_args flag value is now copied from e->is_args when
  calculating complex value length for "if" and "set" directives.
  If e->is_args was set, but le->is_args was not, then buffer overflow
  could happen before 2046b45aa0c6.

5 weeks agoMail: fix session cleanup on error path
Roman Arutyunyan [Sat, 25 Apr 2026 12:41:36 +0000 (16:41 +0400)]
Mail: fix session cleanup on error path

Previously, when ngx_handle_read_event() or ngx_handle_write_event()
returned an error while handling an SMTP, POP3 or IMAP session, the
released session memory could be accessed after handling the error.

5 weeks agoConfigure: fix gcc version detection in some corner cases
Andrew Clayton [Wed, 29 Apr 2026 18:18:03 +0000 (19:18 +0100)]
Configure: fix gcc version detection in some corner cases

If the "gcc version ... " string appeared within "Configured with:", it
was picked up rather than the real gcc version string. This might then
break the configure scripts due to a malformed NGX_COMPILER macro.

The simple fix is to look for "gcc version ... " at the start of the
line, rather than anywhere within.

Suggested-by: Aleksei Bavshin <a.bavshin@nginx.com>
Closes: https://github.com/nginx/nginx/issues/1278
5 weeks agoSSL: logging level of "record layer failure" errors
Sergey Kandaurov [Thu, 16 Apr 2026 13:57:13 +0000 (17:57 +0400)]
SSL: logging level of "record layer failure" errors

The SSL_R_RECORD_LAYER_FAILURE ("record layer failure") errors are
reported by OpenSSL 3.2 or newer as the last record layer error for
various low level read errors.  Further, a976e6b9e (1.23.4) caused
to always log them at the "crit" level.  For example, the following
errors are observed on OpenSSL 3.2.0 - 4.0:

SSL_read() failed (SSL: error:0A000119:SSL routines::decryption failed
 or bad record mac error:0A000139:SSL routines::record layer failure)
SSL_read() failed (SSL: error:1C800066:Provider routines::cipher operation
 failed error:0A000119:SSL routines::decryption failed or bad record mac
 error:0A000139:SSL routines::record layer failure)
SSL_read() failed (SSL: error:0A00010B:SSL routines::wrong version number
 error:0A000139:SSL routines::record layer failure)

These errors are now logged at the "info" level.

Closes: https://github.com/nginx/nginx/issues/961
Co-authored-by: Smeet23 <smeetagrawal2003@gmail.com>
5 weeks agoSSL: compatibility with renamed error codes in OpenSSL 4.0.
Aleksei Bavshin [Tue, 7 Apr 2026 16:26:40 +0000 (09:26 -0700)]
SSL: compatibility with renamed error codes in OpenSSL 4.0.

SSL_R_SSL3_SESSION_ID_TOO_LONG is no longer available when building
OpenSSL 4.0 with no-deprecated.  Added the new name as a fallback.

5 weeks agoSSL: logging level of "invalid alert" errors.
Maxim Dounin [Sun, 5 May 2024 21:07:18 +0000 (00:07 +0300)]
SSL: logging level of "invalid alert" errors.

The SSL_R_INVALID_ALERT ("invalid alert") errors are reported by OpenSSL
1.1.1 or newer if the client sends a malformed alert.  These errors are
now logged at the "info" level.

Signed-off-by: Aleksei Bavshin <a.bavshin@nginx.com>
Origin: <https://freenginx.org/hg/nginx/rev/d89e0386b695>

5 weeks agoSSL: logging level of all "SSL alert number N" errors.
Maxim Dounin [Sun, 5 May 2024 21:06:15 +0000 (00:06 +0300)]
SSL: logging level of all "SSL alert number N" errors.

Errors about alerts received from peers are generated by OpenSSL by adding
peer-provided alert description (from 0 to 255) to SSL_AD_REASON_OFFSET.
All such errors, including ones for unknown alerts, are now logged at the
"info" level, as these can be caused by a misbehaving client.

Signed-off-by: Aleksei Bavshin <a.bavshin@nginx.com>
Origin: <https://freenginx.org/hg/nginx/rev/f5423ee155fe>

5 weeks agoVersion bump
Sergey Kandaurov [Thu, 1 Oct 2026 18:14:53 +0000 (22:14 +0400)]
Version bump

8 weeks agonginx-1.30.5-RELEASE release-1.30.5
Sergey Kandaurov [Tue, 15 Sep 2026 13:02:37 +0000 (17:02 +0400)]
nginx-1.30.5-RELEASE

8 weeks agoQUIC: ignore the QUIC extension received in TLS handshake
Sergey Kandaurov [Thu, 10 Sep 2026 14:38:31 +0000 (18:38 +0400)]
QUIC: ignore the QUIC extension received in TLS handshake

Instead of failing the handshake, it is now accepted and ignored like
any other unknown extension.  Unlike stated in RFC 9001, Section 8.2,
this represents less strict behaviour following RFC 8446, Section 4.2.

8 weeks agoQUIC: registering the compat extension in all SSL contexts
Sergey Kandaurov [Tue, 8 Sep 2026 19:56:38 +0000 (19:56 +0000)]
QUIC: registering the compat extension in all SSL contexts

With the OpenSSL compatibility layer, the transport parameters custom
TLS extension used to be registered only in SSL contexts of virtual
servers reachable over QUIC.

The ClientHello callback introduced in 0373fe5d9 (1.29.2) is called
by OpenSSL between collecting and parsing extensions, so the custom
extensions may not match the expected number if the SSL context was
replaced with SSL_set_SSL_CTX().

The fix is to register the extension in all SSL contexts, including
those that cannot be reached over QUIC, so that the array bounds are
preserved; the compatibility layer as a whole is initialized only
if the configuration has QUIC listeners.  The keylog callback,
meaningful for QUIC connections, is kept on QUIC addresses.

Reported by Banny Liao.

8 weeks agoUpdated OpenSSL and PCRE used for win32 builds
Roman Arutyunyan [Tue, 1 Sep 2026 17:51:10 +0000 (21:51 +0400)]
Updated OpenSSL and PCRE used for win32 builds

8 weeks agoVersion bump
Sergey Kandaurov [Tue, 15 Sep 2026 13:00:26 +0000 (17:00 +0400)]
Version bump

3 months agonginx-1.30.4-RELEASE release-1.30.4
Roman Arutyunyan [Wed, 15 Jul 2026 16:26:09 +0000 (20:26 +0400)]
nginx-1.30.4-RELEASE

3 months agoAvoid duplicate subrequest finalization
Roman Arutyunyan [Mon, 29 Jun 2026 17:49:27 +0000 (21:49 +0400)]
Avoid duplicate subrequest finalization

Previously, if a subrequest was posted twice, it could be finalized in
both calls, excessively reducing r->main->count and potentially leading
to a use-after-free.

The fix is to avoid posting a request if it's already posted.  Also,
as a hardening measure, r->write_event_handler is now reset to a no-op
handler during active subrequest finalization.

The problem manifests itself in ngx_http_ssi_filter_module during
unbuffered proxying.  If a subrequest is created for an SSI include
statement while the main request has some data postponed by another
include, this subrequest becomes double-posted when the main request
data is flushed.  The first post comes from ngx_http_subrequest() and
the second one comes from ngx_http_postpone_filter().  In case of a
quick subrequest finalization, the above mentioned problem happens.

Reported by P4P3R-HAK.

3 months agoFixed uninitialized memory read caused by stale regex captures.
Pavel Pautov [Fri, 15 May 2026 07:48:50 +0000 (00:48 -0700)]
Fixed uninitialized memory read caused by stale regex captures.

When ngx_http_regex_exec() reallocates r->captures array, it doesn't update
r->ncaptures value, if regex didn't match. So the next use of unnamed regex
capture triggers uninitialized read and potential buffer overrun.

This config demonstrates the issue:
    map test $my_map {
        volatile;

        ~mismatch(.*) 1; # reallocates r->captures in subrequests

        default "";
    }

    server {
        location ~(.*) { # sets r->ncaptures
            slice 50;

            # $1 will read from uninitialized memory in slice subrequests
            proxy_set_header Test $my_map$1;

            proxy_set_header Range $slice_range;
            proxy_pass http://backend;
        }
    }

The issue was introduced by 746fba0d79c6.

3 months agoScript: avoid garbage at the end of the result string
Roman Arutyunyan [Fri, 3 Jul 2026 11:11:09 +0000 (15:11 +0400)]
Script: avoid garbage at the end of the result string

If the script result turned out to be shorter than its predicted
length, the result string contained uninitialized bytes at the end.
The fix is to cut the result string by its actual size.

The following locations returned trailing garbage to the client with
URI "/1234abcd".

    map $uri $foo {
        ~^/(?<bar>[0-9]).*$ $bar;
    }

    location ~(?<bar>[0-9]*)[a-z]*$ {
        return 200 $1:$foo;
    }

    location ~(?<bar>[0-9]*)[a-z]*$ {
        set $qux $1:$foo;
        return 200 $qux;
    }

3 months agoScript: buffer overrun protection in direct script usage.
Maxim Dounin [Fri, 19 Jun 2026 19:54:46 +0000 (22:54 +0300)]
Script: buffer overrun protection in direct script usage.

Following the previous change, this change adds script overrun
protection to direct script evaluation in the proxy, fastcgi, scgi,
uwsgi, grpc proxy, index, and try_files modules.

This change is a modified version of a patch by Maxim Dounin.  The
modifications include ngx_http_proxy_v2_module and hardened size checks.

Signed-off-by: Roman Arutyunyan <arut@nginx.com>
Origin: <https://freenginx.org/hg/nginx/rev/7e4d7feb4c77>

3 months agoAccess log: buffer overrun protection.
Maxim Dounin [Fri, 19 Jun 2026 19:55:38 +0000 (22:55 +0300)]
Access log: buffer overrun protection.

Similarly to generic script operations, access log script copy operations
now check if there is enough room in the buffer.

Signed-off-by: Roman Arutyunyan <arut@nginx.com>
Origin: <https://freenginx.org/hg/nginx/rev/ceff7ca7785a>

3 months agoScript: buffer overrun protection.
Maxim Dounin [Fri, 19 Jun 2026 19:54:27 +0000 (22:54 +0300)]
Script: buffer overrun protection.

With this change, all script copy operations now check if there is
enough room in the buffer.  To do so, the script engine now provides the
e->end pointer, which specifies expected buffer end, and each copy
operation is checked against it with the ngx_http_script_check_length()
function.

The e->end pointer is optional and only checked when set, thus
introducing no incompatible API changes.  All standard functions were
updated to use it, notably ngx_http_complex_value(), ngx_http_script_run(),
ngx_http_script_regex_start_code(), ngx_http_script_complex_value_code().
Direct script evaluation in the proxy, fastcgi, scgi, uwsgi, grpc proxy,
index, and try_files modules will be updated by a separate patch.

In particular, this catches issues as observed when evaluating variables
with side effects, such as in the following configuration:

    map $uri $map {
        ~(?<capture>.*) $capture;
    }

    set $capture "";
    set $temp "$capture $map";

As well as when evaluating non-cacheable variables, where length of a
variable might change between length and copy codes, such as in the
following configuration:

    map prefix:$capture $map_volatile {
        volatile;
        ~(?<capture>.*) $capture;
    }

    set $capture "";
    set $temp "$map_volatile";

Similar changes were made in the stream module.

Signed-off-by: Roman Arutyunyan <arut@nginx.com>
Origin: <https://freenginx.org/hg/nginx/rev/d172f506ab5f>

3 months agoScript: simplified copy capture codes.
Maxim Dounin [Fri, 19 Jun 2026 19:54:19 +0000 (22:54 +0300)]
Script: simplified copy capture codes.

Signed-off-by: Roman Arutyunyan <arut@nginx.com>
Origin: <https://freenginx.org/hg/nginx/rev/0fd5e6155817>

3 months agoVersion bump
Roman Arutyunyan [Wed, 15 Jul 2026 16:20:17 +0000 (20:20 +0400)]
Version bump

4 months agonginx-1.30.3-RELEASE release-1.30.3
Roman Arutyunyan [Tue, 16 Jun 2026 23:00:27 +0000 (03:00 +0400)]
nginx-1.30.3-RELEASE

4 months agoCharset: fixed another rare buffer overread in recode_from_utf8()
Sergey Kandaurov [Mon, 1 Jun 2026 17:46:48 +0000 (21:46 +0400)]
Charset: fixed another rare buffer overread in recode_from_utf8()

With prerequisites similar to 696a7f1b9, it was possible to gain 1-byte
overread on invalid UTF-8 sequences.  The reason is ngx_utf8_decode()
stops advancing the pointer position on the first encountered invalid
byte.  The fix is to adjust the advanced pointer up to the whole saved
sequence in this case.  Note that this may result in different output
compared to complete invalid UTF-8 sequences, which we can disregard
at this point.

Reported by Han Yan of Xiaomi and p4p3r of CYBERONE.

4 months agoUpstream: limit header length for HTTP/2 and gRPC
Roman Arutyunyan [Tue, 2 Jun 2026 15:37:17 +0000 (19:37 +0400)]
Upstream: limit header length for HTTP/2 and gRPC

The change applies the HTTP/2 header length limits to avoid buffer
overflow.  See 58a7bc3406ac for details.

Reported by Mufeed VH of Winfunc Research.

4 months agoUpdated OpenSSL used for win32 builds
Sergey Kandaurov [Tue, 16 Jun 2026 15:30:59 +0000 (19:30 +0400)]
Updated OpenSSL used for win32 builds

4 months agoVersion bump
Roman Arutyunyan [Tue, 16 Jun 2026 22:54:38 +0000 (02:54 +0400)]
Version bump

5 months agonginx-1.30.2-RELEASE release-1.30.2
Sergey Kandaurov [Fri, 22 May 2026 10:23:35 +0000 (14:23 +0400)]
nginx-1.30.2-RELEASE

5 months agoRewrite: fix buffer overflow with overlapping captures
Roman Arutyunyan [Thu, 14 May 2026 14:42:18 +0000 (18:42 +0400)]
Rewrite: fix buffer overflow with overlapping captures

When the rewrite replacement string had no variables, but had
overlapping captures, the length of the allocated buffer could be
smaller than the replacement string.  This could happen either
when the "redirect" parameter is specified, or when arguments are
present in the replacement string.

The following configurations resulted in heap buffer overflow when
using URI "/++++++++++++++++++++++++++++++":

    location / {
        rewrite ^/((.*))$ http://127.0.0.1:8080/$1$2 redirect;
        return 200 foo;
    }

    location / {
        rewrite ^/((.*))$ http://127.0.0.1:8080/?$1$2;
        return 200 foo;
    }

Reported by Mufeed VH of Winfunc Research.

5 months agoVersion bump
Sergey Kandaurov [Fri, 22 May 2026 10:22:39 +0000 (14:22 +0400)]
Version bump

5 months agonginx-1.30.1-RELEASE release-1.30.1
Sergey Kandaurov [Wed, 13 May 2026 11:34:55 +0000 (15:34 +0400)]
nginx-1.30.1-RELEASE

5 months agoProxy: fix large body with proxy_set_body and HTTP/2
Roman Arutyunyan [Mon, 4 May 2026 14:43:17 +0000 (18:43 +0400)]
Proxy: fix large body with proxy_set_body and HTTP/2

Previously, if proxy_set_body was used with HTTP/2, and body size exceeded
16M, then an overflow happened in the 24-bit DATA frame size, which resulted
in sending unframed bytes, potentially allowing for an injection.

Also, DATA frame size could exceed NGX_HTTP_V2_DEFAULT_FRAME_SIZE (16K) and
available send window.

Reported by Mufeed VH of Winfunc Research.

5 months agoRewrite: fixed escaping and possible buffer overrun
Roman Arutyunyan [Wed, 22 Apr 2026 05:39:31 +0000 (09:39 +0400)]
Rewrite: fixed escaping and possible buffer overrun

The following code resulted in incorrect escaping of $1 and possible
segfault:

    location / {
        rewrite ^(.*) /new?c=1;
        set $myvar $1;
        return 200 $myvar;
    }

If there were arguments in a rewrite's replacement string, the is_args flag
was set and incorrectly never cleared.  This resulted in escaping applied
to any captures evaluated afterwards in set or if.  Additionally buffer was
allocated by ngx_http_script_complex_value_code() without escaping expected,
thus this also resulted in buffer overrun and possible segfault.

A similar issue was fixed in 74d939974d43.

Reported by Leo Lin.

5 months agoUpstream: fixed parsing of split status lines
Sergey Kandaurov [Wed, 29 Apr 2026 19:02:20 +0000 (23:02 +0400)]
Upstream: fixed parsing of split status lines

If the first response line was split across reads and it didn't appear
a status line, the portion already processed was lost.  To preserve ABI,
the change reuses r->header_name_start for proper backtracking on status
line fallback.

5 months agoUpstream: reset parsing state after invalid status line
Sergey Kandaurov [Wed, 29 Apr 2026 17:56:51 +0000 (21:56 +0400)]
Upstream: reset parsing state after invalid status line

Previously, it was possible to start parsing headers with a wrong
parsing state after status line was not recognized, as a fallback
used in the scgi and uwsgi modules.

Reported by Leo Lin.

5 months agoCharset: fix buffer over-read in recode_from_utf8().
David Carlier [Sun, 12 Apr 2026 06:13:23 +0000 (07:13 +0100)]
Charset: fix buffer over-read in recode_from_utf8().

When a multi-byte UTF-8 character was split across 3+ single-byte
buffers, the saved bytes continuation path had two related bugs:

ngx_utf8_decode() was called with the last saved-array index instead
of the byte count, causing it to report "incomplete" even when the
sequence was already complete.

The subsequent ngx_memcpy() used that same index as the copy length,
reading past the input buffer boundary.

5 months agoQUIC: avoid assigning unvalidated address to new streams
Roman Arutyunyan [Thu, 30 Apr 2026 13:15:53 +0000 (17:15 +0400)]
QUIC: avoid assigning unvalidated address to new streams

Previously, when a client migrated to a new address, new QUIC streams
received this address before validation.  This allowed an attacker to
create QUIC streams with a spoofed address.

Reported by Rodrigo Laneth.

5 months agoOCSP: resolve cleanup on connection close
Roman Arutyunyan [Tue, 21 Apr 2026 10:51:41 +0000 (14:51 +0400)]
OCSP: resolve cleanup on connection close

Previously, when a client SSL connection was terminated (typically due to a
timeout) while resolving an OCSP responder, the OCSP context was freed, but
the resolve context was not.  This resulted in use-after-free on resolve
completion.

Reported by Leo Lin.

5 months agoProxy: fix keepalive for HTTP/2 with explicit or no body
Roman Arutyunyan [Tue, 5 May 2026 11:22:05 +0000 (15:22 +0400)]
Proxy: fix keepalive for HTTP/2 with explicit or no body

Previously, when an HTTP/2 request had no body or an explicit body
was set by proxy_set_body, the request consisted of only one buffer,
which had no b->last_buf flag set.  This prevented ctx->output_closed
from being set after processing this buffer.  Consequently,
u->keepalive might not be set to store the connection in the
keepalive cache.

5 months agoVersion bump
Sergey Kandaurov [Wed, 13 May 2026 11:05:28 +0000 (15:05 +0400)]
Version bump

6 months agonginx-1.30.0-RELEASE release-1.30.0
Sergey Kandaurov [Tue, 14 Apr 2026 13:03:28 +0000 (17:03 +0400)]
nginx-1.30.0-RELEASE

6 months agoUpdated OpenSSL used for win32 builds
Sergey Kandaurov [Tue, 14 Apr 2026 12:48:30 +0000 (16:48 +0400)]
Updated OpenSSL used for win32 builds

6 months agoStable branch
Sergey Kandaurov [Tue, 14 Apr 2026 09:25:34 +0000 (13:25 +0400)]
Stable branch

7 months agonginx-1.29.8-RELEASE release-1.29.8
Sergey Kandaurov [Mon, 6 Apr 2026 17:40:05 +0000 (21:40 +0400)]
nginx-1.29.8-RELEASE

7 months agoUpstream: reset early_hints_length on upstream reinit.
David Carlier [Sun, 15 Mar 2026 15:56:01 +0000 (15:56 +0000)]
Upstream: reset early_hints_length on upstream reinit.

When a request was retried to a new upstream after receiving 103
Early Hints from the previous one, the accumulated early_hints_length
was not reset, causing valid early hints from the next upstream to be
incorrectly rejected as "too big".

7 months agoFix $request_port and $is_request_port in subrequests
Zoey [Sun, 5 Apr 2026 09:31:15 +0000 (11:31 +0200)]
Fix $request_port and $is_request_port in subrequests

Closes #1247.

7 months agoAdded max_headers directive.
Maxim Dounin [Thu, 23 May 2024 21:20:01 +0000 (00:20 +0300)]
Added max_headers directive.

The directive limits the number of request headers accepted from clients.
While the total amount of headers is believed to be sufficiently limited
by the existing buffer size limits (client_header_buffer_size and
large_client_header_buffers), the additional limit on the number of headers
might be beneficial to better protect backend servers.

Requested by Maksim Yevmenkin.

Signed-off-by: Elijah Zupancic <e.zupancic@f5.com>
Origin: <https://freenginx.org/hg/nginx/rev/199dc0d6b05be814b5c811876c20af58cd361fea>

7 months agoUpstream: fix integer underflow in charset parsing
David Korczynski [Wed, 4 Mar 2026 09:27:45 +0000 (01:27 -0800)]
Upstream: fix integer underflow in charset parsing

The issue described below was only reproducible prior to
https://github.com/nginx/nginx/commit/7924a4ec6cb35291ea60a5f2a70ac0a034d94ff7

When parsing the `charset` parameter in the `Content-Type` header within
`ngx_http_upstream_copy_content_type`, an input such as `charset="`
resulted in an integer underflow.

In this scenario, both `p` and `last` point to the position immediately
following the opening quote. The logic to strip a trailing quote checked
`*(last - 1)` without verifying that `last > p`. This caused `last` to
be decremented to point to the opening quote itself, making `last < p`.

The subsequent length calculation `r->headers_out.charset.len = last - p`
resulted in -1, which wrapped to `SIZE_MAX` as `len` is a `size_t`. This
invalid length was later passed to `ngx_cpymem` in `ngx_http_header_filter`,
leading to an out-of-bounds memory access (detected as
`negative-size-param` by AddressSanitizer).

The fix ensures `last > p` before attempting to strip a trailing quote,
correctly resulting in a zero-length charset for malformed input.

The oss-fuzz payload that triggers this issue holds multiple 103 status
lines, and it's a sequence of 2 of those Content-Type headers that
trigger the ASAN report.

Co-authored-by: CodeMender <codemender-patching@google.com>
Fixes: https://issues.oss-fuzz.com/issues/486561029
Signed-off-by: David Korczynski <david@adalogics.com>
7 months agoRemoved CLOCK_MONOTONIC_FAST support.
Eugene Grebenschikov [Wed, 1 Apr 2026 18:03:21 +0000 (11:03 -0700)]
Removed CLOCK_MONOTONIC_FAST support.

CLOCK_MONOTONIC_FAST, like CLOCK_MONOTONIC_COARSE, has low accuracy. It
shows noticeable timing variation for short intervals, which is visible
in metrics like $upstream_response_time for fast upstream responses.
This change complements the work started in commit f29d7ade5.
In addition to the reasons described in f29d7ade5, the performance of
CLOCK_MONOTONIC is good enough on modern hardware when using a TSC
timecounter. This is especially true when it is accessed through a
shared page, as implemented in FreeBSD 10.0 (see git commits
869fd80fd449 and aea810386d8e for details).

Co-authored-by: Sergey Kandaurov <pluknet@nginx.com>
7 months agoUpstream: fixed processing multiple 103 (early hints) responses.
Sergey Kandaurov [Thu, 2 Apr 2026 13:41:56 +0000 (17:41 +0400)]
Upstream: fixed processing multiple 103 (early hints) responses.

The second 103 response in a row was treated as the final response header.

7 months agoUpdate CONTRIBUTING.md
xuruidong [Thu, 19 Mar 2026 13:02:05 +0000 (21:02 +0800)]
Update CONTRIBUTING.md

7 months agoSSL: compatibility with OpenSSL 4.0.
Sergey Kandaurov [Tue, 10 Mar 2026 12:28:04 +0000 (16:28 +0400)]
SSL: compatibility with OpenSSL 4.0.

X509_get_issuer_name() and X509_get_subject_name() were changed to return
a const value.  Since it is passed to functions with a non const argument
in older versions, the const modifier is conditionally compiled as needed.

ASN1_INTEGER was made opaque.  ASN1_STRING accessors are used to preserve
the behaviour.  ASN1_STRING_get0_data() compat shim is provided for OpenSSL
< 1.1.0 where it does not exist.

7 months agoVersion bump.
Sergey Kandaurov [Mon, 30 Mar 2026 15:26:17 +0000 (19:26 +0400)]
Version bump.

7 months agoFixed the "include" directive inside the "geo" block.
Eugene Grebenschikov [Thu, 12 Mar 2026 00:57:05 +0000 (17:57 -0700)]
Fixed the "include" directive inside the "geo" block.

The "include" directive should be able to include multiple files if
given a filename mask.

Completes remaining changes introduced in da4ffd8.

Closes: https://github.com/nginx/nginx/issues/1165
7 months agonginx-1.29.7-RELEASE release-1.29.7
Roman Arutyunyan [Thu, 19 Mar 2026 14:53:00 +0000 (18:53 +0400)]
nginx-1.29.7-RELEASE

7 months agoStream: fixed client certificate validation with OCSP.
Sergey Kandaurov [Tue, 17 Mar 2026 15:20:03 +0000 (19:20 +0400)]
Stream: fixed client certificate validation with OCSP.

Check for OCSP status was missed in 581cf2267, resulting
in a broken validation.

Reported by Mufeed VH of Winfunc Research.

7 months agoMail: fixed clearing s->passwd in auth http requests.
Sergey Kandaurov [Wed, 18 Mar 2026 12:39:37 +0000 (16:39 +0400)]
Mail: fixed clearing s->passwd in auth http requests.

Previously, it was not properly cleared retaining length as part of
authenticating with CRAM-MD5 and APOP methods that expect to receive
password in auth response.  This resulted in null pointer dereference
and worker process crash in subsequent auth attempts with CRAM-MD5.

Reported by Arkadi Vainbrand.

7 months agoMail: host validation.
Roman Arutyunyan [Thu, 26 Feb 2026 07:52:53 +0000 (11:52 +0400)]
Mail: host validation.

Now host name resolved from client address is validated to only contain
the characters specified in RFC 1034, Section 3.5.  The validation allows
to avoid injections when using the resolved host name in auth_http and
smtp proxy.

Reported by Asim Viladi Oglu Manizada, Colin Warren,
Xiao Liu (Yunnan University), Yuan Tan (UC Riverside), and
Bird Liu (Lanzhou University).

7 months agoDav: destination length validation for COPY and MOVE.
Roman Arutyunyan [Mon, 16 Mar 2026 16:13:03 +0000 (20:13 +0400)]
Dav: destination length validation for COPY and MOVE.

Previously, when alias was used in a location with Dav COPY or MOVE
enabled, and the destination URI was shorter than the alias, integer
underflow could happen in ngx_http_map_uri_to_path(), which could
result in heap buffer overwrite, followed by a possible segfault.
With some implementations of memcpy(), the segfault could be avoided
and the overwrite could result in a change of the source or destination
file names to be outside of the location root.

Reported by Calif.io in collaboration with Claude and Anthropic Research.

7 months agoMp4: fixed possible integer overflow on 32-bit platforms.
Roman Arutyunyan [Mon, 2 Mar 2026 17:12:34 +0000 (21:12 +0400)]
Mp4: fixed possible integer overflow on 32-bit platforms.

Previously, a 32-bit overflow could happen while validating atom entries
count.  This allowed processing of an invalid atom with entrires beyond
its boundaries with reads and writes outside of the allocated mp4 buffer.

Reported by Prabhav Srinath (sprabhav7).

7 months agoMp4: avoid zero size buffers in output.
Roman Arutyunyan [Sat, 21 Feb 2026 08:04:36 +0000 (12:04 +0400)]
Mp4: avoid zero size buffers in output.

Previously, data validation checks did not cover the cases when the output
contained empty buffers.  Such buffers are considered illegal and produce
"zero size buf in output" alerts.  The change rejects the mp4 files which
produce such alerts.

Also, the change fixes possible buffer overread and overwrite that could
happen while processing empty stco and co64 atoms, as reported by
Pavel Kohout (Aisle Research) and Tim Becker.

7 months agoUpstream keepalive: fixed parameter parsing.
Roman Arutyunyan [Tue, 24 Mar 2026 11:12:05 +0000 (15:12 +0400)]
Upstream keepalive: fixed parameter parsing.