<feed xmlns='http://www.w3.org/2005/Atom'>
<title>nginx.git/src/http, branch release-1.26.3</title>
<subtitle>nginx</subtitle>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/'/>
<entry>
<title>SNI: added restriction for TLSv1.3 cross-SNI session resumption.</title>
<updated>2025-02-05T16:40:47+00:00</updated>
<author>
<name>Sergey Kandaurov</name>
<email>pluknet@nginx.com</email>
</author>
<published>2025-01-22T14:55:44+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=13935cf9fdc3c8d8278c70716417d3b71c36140e'/>
<id>13935cf9fdc3c8d8278c70716417d3b71c36140e</id>
<content type='text'>
In OpenSSL, session resumption always happens in the default SSL context,
prior to invoking the SNI callback.  Further, unlike in TLSv1.2 and older
protocols, SSL_get_servername() returns values received in the resumption
handshake, which may be different from the value in the initial handshake.
Notably, this makes the restriction added in b720f650b insufficient for
sessions resumed with different SNI server name.

Considering the example from b720f650b, previously, a client was able to
request example.org by presenting a certificate for example.org, then to
resume and request example.com.

The fix is to reject handshakes resumed with a different server name, if
verification of client certificates is enabled in a corresponding server
configuration.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
In OpenSSL, session resumption always happens in the default SSL context,
prior to invoking the SNI callback.  Further, unlike in TLSv1.2 and older
protocols, SSL_get_servername() returns values received in the resumption
handshake, which may be different from the value in the initial handshake.
Notably, this makes the restriction added in b720f650b insufficient for
sessions resumed with different SNI server name.

Considering the example from b720f650b, previously, a client was able to
request example.org by presenting a certificate for example.org, then to
resume and request example.com.

The fix is to reject handshakes resumed with a different server name, if
verification of client certificates is enabled in a corresponding server
configuration.
</pre>
</div>
</content>
</entry>
<entry>
<title>Gzip: compatibility with recent zlib-ng 2.2.x versions.</title>
<updated>2025-02-05T16:40:47+00:00</updated>
<author>
<name>Sergey Kandaurov</name>
<email>pluknet@nginx.com</email>
</author>
<published>2024-12-23T13:57:45+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=9cda58178bf6d552829d20fedee1d4df564f5629'/>
<id>9cda58178bf6d552829d20fedee1d4df564f5629</id>
<content type='text'>
It now uses 5/4 times more memory for the pending buffer.

Further, a single allocation is now used, which takes additional 56 bytes
for deflate_allocs in 64-bit mode aligned to 16, to store sub-allocation
pointers, and the total allocation size now padded up to 128 bytes, which
takes theoretically 200 additional bytes in total.  This fits though into
"4 * (64 + sizeof(void*))" additional space for ZALLOC used in zlib-ng
2.1.x versions.  The comment was updated to reflect this.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
It now uses 5/4 times more memory for the pending buffer.

Further, a single allocation is now used, which takes additional 56 bytes
for deflate_allocs in 64-bit mode aligned to 16, to store sub-allocation
pointers, and the total allocation size now padded up to 128 bytes, which
takes theoretically 200 additional bytes in total.  This fits though into
"4 * (64 + sizeof(void*))" additional space for ZALLOC used in zlib-ng
2.1.x versions.  The comment was updated to reflect this.
</pre>
</div>
</content>
</entry>
<entry>
<title>Mp4: prevent chunk index underflow.</title>
<updated>2025-02-05T16:40:47+00:00</updated>
<author>
<name>Roman Arutyunyan</name>
<email>arut@nginx.com</email>
</author>
<published>2024-10-22T14:34:13+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=e9e83dbb697c17b7ad51d1dd8536ad1c601fdd0e'/>
<id>e9e83dbb697c17b7ad51d1dd8536ad1c601fdd0e</id>
<content type='text'>
When cropping stsc atom, it's assumed that chunk index is never 0.
Based on this assumption, start_chunk and end_chunk are calculated
by subtracting 1 from it.  If chunk index is zero, start_chunk or
end_chunk may underflow, which will later trigger
"start/end time is out mp4 stco chunks" error.  The change adds an
explicit check for zero chunk index to avoid underflow and report
a proper error.

Zero chunk index is explicitly banned in ISO/IEC 14496-12, 8.7.4
Sample To Chunk Box.  It's also implicitly banned in QuickTime File
Format specification.  Description of chunk offset table references
"Chunk 1" as the first table element.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
When cropping stsc atom, it's assumed that chunk index is never 0.
Based on this assumption, start_chunk and end_chunk are calculated
by subtracting 1 from it.  If chunk index is zero, start_chunk or
end_chunk may underflow, which will later trigger
"start/end time is out mp4 stco chunks" error.  The change adds an
explicit check for zero chunk index to avoid underflow and report
a proper error.

Zero chunk index is explicitly banned in ISO/IEC 14496-12, 8.7.4
Sample To Chunk Box.  It's also implicitly banned in QuickTime File
Format specification.  Description of chunk offset table references
"Chunk 1" as the first table element.
</pre>
</div>
</content>
</entry>
<entry>
<title>Mp4: unordered stsc chunks error for the final chunk.</title>
<updated>2025-02-05T16:40:47+00:00</updated>
<author>
<name>Roman Arutyunyan</name>
<email>arut@nginx.com</email>
</author>
<published>2024-10-02T12:22:15+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=1ebe58a02e90a65458de0a38c84165b2a37574ed'/>
<id>1ebe58a02e90a65458de0a38c84165b2a37574ed</id>
<content type='text'>
Currently an error is triggered if any of the chunk runs in stsc are
unordered.  This however does not include the final chunk run, which
ends with trak-&gt;chunks + 1.  The previous chunk index can be larger
leading to a 32-bit overflow.  This could allow to skip the validity
check "if (start_sample &gt; n)".  This could later lead to a large
trak-&gt;start_chunk/trak-&gt;end_chunk, which would be caught later in
ngx_http_mp4_update_stco_atom() or ngx_http_mp4_update_co64_atom().

While there are no implications of the validity check being avoided,
the change still adds a check to ensure the final chunk run is ordered,
to produce a meaningful error and avoid a potential integer overflow.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Currently an error is triggered if any of the chunk runs in stsc are
unordered.  This however does not include the final chunk run, which
ends with trak-&gt;chunks + 1.  The previous chunk index can be larger
leading to a 32-bit overflow.  This could allow to skip the validity
check "if (start_sample &gt; n)".  This could later lead to a large
trak-&gt;start_chunk/trak-&gt;end_chunk, which would be caught later in
ngx_http_mp4_update_stco_atom() or ngx_http_mp4_update_co64_atom().

While there are no implications of the validity check being avoided,
the change still adds a check to ensure the final chunk run is ordered,
to produce a meaningful error and avoid a potential integer overflow.
</pre>
</div>
</content>
</entry>
<entry>
<title>Mp4: fixed handling an empty run of chunks in stsc atom.</title>
<updated>2025-02-05T16:40:47+00:00</updated>
<author>
<name>Roman Arutyunyan</name>
<email>arut@nginx.com</email>
</author>
<published>2024-09-23T11:51:30+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=4712dee8820cf6af417b1932d9ef65774a1ee1b3'/>
<id>4712dee8820cf6af417b1932d9ef65774a1ee1b3</id>
<content type='text'>
A specially crafted mp4 file with an empty run of chunks in the stsc atom
and a large value for samples per chunk for that run, combined with a
specially crafted request, allowed to store that large value in prev_samples
and later in trak-&gt;end_chunk_samples while in ngx_http_mp4_crop_stsc_data().
Later in ngx_http_mp4_update_stsz_atom() this could result in buffer
overread while calculating trak-&gt;end_chunk_samples_size.

Now the value of samples per chunk specified for an empty run is ignored.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
A specially crafted mp4 file with an empty run of chunks in the stsc atom
and a large value for samples per chunk for that run, combined with a
specially crafted request, allowed to store that large value in prev_samples
and later in trak-&gt;end_chunk_samples while in ngx_http_mp4_crop_stsc_data().
Later in ngx_http_mp4_update_stsz_atom() this could result in buffer
overread while calculating trak-&gt;end_chunk_samples_size.

Now the value of samples per chunk specified for an empty run is ignored.
</pre>
</div>
</content>
</entry>
<entry>
<title>Mp4: rejecting unordered chunks in stsc atom.</title>
<updated>2024-08-12T14:20:45+00:00</updated>
<author>
<name>Roman Arutyunyan</name>
<email>arut@nginx.com</email>
</author>
<published>2024-08-12T14:20:45+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=2262362fd31eee3e74eb6abe4451ad6ab51e3643'/>
<id>2262362fd31eee3e74eb6abe4451ad6ab51e3643</id>
<content type='text'>
Unordered chunks could result in trak-&gt;end_chunk smaller than trak-&gt;start_chunk
in ngx_http_mp4_crop_stsc_data().  Later in ngx_http_mp4_update_stco_atom()
this caused buffer overread while trying to calculate trak-&gt;end_offset.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Unordered chunks could result in trak-&gt;end_chunk smaller than trak-&gt;start_chunk
in ngx_http_mp4_crop_stsc_data().  Later in ngx_http_mp4_update_stco_atom()
this caused buffer overread while trying to calculate trak-&gt;end_offset.
</pre>
</div>
</content>
</entry>
<entry>
<title>Mp4: fixed buffer underread while updating stsz atom.</title>
<updated>2024-08-12T14:20:43+00:00</updated>
<author>
<name>Roman Arutyunyan</name>
<email>arut@nginx.com</email>
</author>
<published>2024-08-12T14:20:43+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=3dc0fba5adec4c033eed76976f7275f2af7d5ddd'/>
<id>3dc0fba5adec4c033eed76976f7275f2af7d5ddd</id>
<content type='text'>
While cropping an stsc atom in ngx_http_mp4_crop_stsc_data(), a 32-bit integer
overflow could happen, which could result in incorrect seeking and a very large
value stored in "samples".  This resulted in a large invalid value of
trak-&gt;end_chunk_samples.  This value is further used to calculate the value of
trak-&gt;end_chunk_samples_size in ngx_http_mp4_update_stsz_atom().  While doing
this, a large invalid value of trak-&gt;end_chunk_samples could result in reading
memory before stsz atom start.  This could potentially result in a segfault.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
While cropping an stsc atom in ngx_http_mp4_crop_stsc_data(), a 32-bit integer
overflow could happen, which could result in incorrect seeking and a very large
value stored in "samples".  This resulted in a large invalid value of
trak-&gt;end_chunk_samples.  This value is further used to calculate the value of
trak-&gt;end_chunk_samples_size in ngx_http_mp4_update_stsz_atom().  While doing
this, a large invalid value of trak-&gt;end_chunk_samples could result in reading
memory before stsz atom start.  This could potentially result in a segfault.
</pre>
</div>
</content>
</entry>
<entry>
<title>HTTP/3: fixed handling of zero-length literal field line.</title>
<updated>2024-05-28T13:20:45+00:00</updated>
<author>
<name>Sergey Kandaurov</name>
<email>pluknet@nginx.com</email>
</author>
<published>2024-05-28T13:20:45+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=ffed470390784524800ca38dd415c2d71442c6c2'/>
<id>ffed470390784524800ca38dd415c2d71442c6c2</id>
<content type='text'>
Previously, st-&gt;value was passed with NULL data pointer to header handlers.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Previously, st-&gt;value was passed with NULL data pointer to header handlers.
</pre>
</div>
</content>
</entry>
<entry>
<title>HTTP/3: fixed dynamic table overflow.</title>
<updated>2024-05-28T13:18:50+00:00</updated>
<author>
<name>Roman Arutyunyan</name>
<email>arut@nginx.com</email>
</author>
<published>2024-05-28T13:18:50+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=3f2d8cb8f92d3c3468478651b58607f1576a12ac'/>
<id>3f2d8cb8f92d3c3468478651b58607f1576a12ac</id>
<content type='text'>
While inserting a new entry into the dynamic table, first the entry is added,
and then older entries are evicted until table size is within capacity.  After
the first step, the number of entries may temporarily exceed the maximum
calculated from capacity by one entry, which previously caused table overflow.

The easiest way to trigger the issue is to keep adding entries with empty names
and values until first eviction.

The issue was introduced by 987bee4363d1.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
While inserting a new entry into the dynamic table, first the entry is added,
and then older entries are evicted until table size is within capacity.  After
the first step, the number of entries may temporarily exceed the maximum
calculated from capacity by one entry, which previously caused table overflow.

The easiest way to trigger the issue is to keep adding entries with empty names
and values until first eviction.

The issue was introduced by 987bee4363d1.
</pre>
</div>
</content>
</entry>
<entry>
<title>HTTP/3: decoder stream pre-creation.</title>
<updated>2024-05-28T13:18:28+00:00</updated>
<author>
<name>Roman Arutyunyan</name>
<email>arut@nginx.com</email>
</author>
<published>2024-05-28T13:18:28+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=326150b82d5a345dfb8799f2f52e987760ea242e'/>
<id>326150b82d5a345dfb8799f2f52e987760ea242e</id>
<content type='text'>
Previously a decoder stream was created on demand for sending Section
Acknowledgement, Stream Cancellation and Insert Count Increment.  If conditions
for sending any of these instructions never happen, a decoder stream is not
created at all.  These conditions include client not using the dynamic table and
no streams abandoned by server (RFC 9204, Section 2.2.2.2).  However RFC 9204,
Section 4.2 defines only one condition for not creating a decoder stream:

   An endpoint MAY avoid creating a decoder stream if its decoder sets
   the maximum capacity of the dynamic table to zero.

The change enables pre-creation of the decoder stream at HTTP/3 session
initialization if maximum dynamic table capacity is not zero.  Note that this
value is currently hardcoded to 4096 bytes and is not configurable, so the
stream is now always created.

Also, the change fixes a potential stack overflow when creating a decoder
stream in ngx_http_v3_send_cancel_stream() while draining a request stream by
ngx_drain_connections().  Creating a decoder stream involves calling
ngx_get_connection(), which calls ngx_drain_connections(), which will drain the
same request stream again.  If client's MAX_STREAMS for uni stream is high
enough, these recursive calls will continue until we run out of stack.
Otherwise, decoder stream creation will fail at some point and the request
stream connection will be drained.  This may result in use-after-free, since
this connection could still be referenced up the stack.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Previously a decoder stream was created on demand for sending Section
Acknowledgement, Stream Cancellation and Insert Count Increment.  If conditions
for sending any of these instructions never happen, a decoder stream is not
created at all.  These conditions include client not using the dynamic table and
no streams abandoned by server (RFC 9204, Section 2.2.2.2).  However RFC 9204,
Section 4.2 defines only one condition for not creating a decoder stream:

   An endpoint MAY avoid creating a decoder stream if its decoder sets
   the maximum capacity of the dynamic table to zero.

The change enables pre-creation of the decoder stream at HTTP/3 session
initialization if maximum dynamic table capacity is not zero.  Note that this
value is currently hardcoded to 4096 bytes and is not configurable, so the
stream is now always created.

Also, the change fixes a potential stack overflow when creating a decoder
stream in ngx_http_v3_send_cancel_stream() while draining a request stream by
ngx_drain_connections().  Creating a decoder stream involves calling
ngx_get_connection(), which calls ngx_drain_connections(), which will drain the
same request stream again.  If client's MAX_STREAMS for uni stream is high
enough, these recursive calls will continue until we run out of stack.
Otherwise, decoder stream creation will fail at some point and the request
stream connection will be drained.  This may result in use-after-free, since
this connection could still be referenced up the stack.
</pre>
</div>
</content>
</entry>
</feed>
