Commit Graph

8430 Commits

Author SHA1 Message Date
Demi Marie Obenour
31696f8481
Merge 9b8e4a1937 into c52c5698cd 2025-07-11 20:51:04 +02:00
Sergey Kandaurov
c52c5698cd Events: compatibility with NetBSD 10.0 in kqueue.
Some checks failed
buildbot / buildbot (push) Has been cancelled
The kevent udata field was changed from intptr_t to "void *",
similar to other BSDs and Darwin.

The NGX_KQUEUE_UDATA_T macro is adjusted to reflect that change,
fixing -Werror=int-conversion errors.
2025-07-11 16:25:51 +04:00
Sergey Kandaurov
3f5f8a7f51 Configure: set NGX_KQUEUE_UDATA_T at compile time.
The NGX_KQUEUE_UDATA_T macro is used to compensate the incompatible
kqueue() API in NetBSD, it doesn't really belong to feature tests.

The change limits the macro visibility to the kqueue event module.
Moving from autotests also simplifies testing a particular NetBSD
version as seen in a subsequent change.
2025-07-11 16:25:51 +04:00
Sergey Kandaurov
0daaba5c54 Events: fixed -Wzero-as-null-pointer-constant warnings in kqueue.
The kevent udata field is special in that we maintain compatibility
with NetBSD versions that predate using the "void *" type.

The fix is to cast to intermediate uintptr_t that is casted back to
"void *" where appropriate.
2025-07-11 16:25:51 +04:00
Sergey Kandaurov
a5ca38f303 SSL: fixed testing OPENSSL_VERSION_NUMBER for OpenSSL 3.0+.
Prior to OpenSSL 3.0, OPENSSL_VERSION_NUMBER used the following format:

MNNFFPPS: major minor fix patch status

Where the status nibble (S) has 0+ for development and f for release.

The format was changed in OpenSSL 3.0.0, where it is always zero:

MNN00PP0: major minor patch
2025-07-10 19:00:45 +04:00
Sergey Kandaurov
a5d60c30d3 SSL: SSL_group_to_name() compatibility macro.
No functional changes.
2025-07-10 19:00:45 +04:00
Sergey Kandaurov
0bb7489cb2 QUIC: adjusted OpenSSL 3.5 QUIC API feature test.
A bug with the "quic_transport_parameters" extension and SNI described
in cedb855d7 is now fixed in the OpenSSL 3.5.1 release, as requested
in https://github.com/openssl/openssl/pull/27706.
2025-07-03 22:50:25 +04:00
Sergey Kandaurov
d1843e1d9b Win32: fixed PCRE license for nginx/Windows zip.
Some checks failed
buildbot / buildbot (push) Has been cancelled
2025-06-25 14:19:13 +04:00
Sergey Kandaurov
279fe352cb Version bump. 2025-06-25 14:19:13 +04:00
Sergey Kandaurov
235f409907 nginx-1.29.0-RELEASE
Some checks are pending
buildbot / buildbot (push) Waiting to run
2025-06-24 21:22:41 +04:00
Sergey Kandaurov
1263d6bec3 Updated OpenSSL and PCRE used for win32 builds. 2025-06-24 21:22:41 +04:00
Sergey Kandaurov
b997be14f5 Win32: skip OpenSSL dependency generation to conserve time.
Disabling the build dependency feature is safe assuming that
nginx/Windows release zip is always built from a clean tree.
This allows to speed up total build time by around 40%.

As it may not be suitable in general, the option resides here
and not in configure.
2025-06-24 21:22:41 +04:00
Sergey Kandaurov
cedb855d75 QUIC: disabled OpenSSL 3.5 QUIC API support by default.
Some checks are pending
buildbot / buildbot (push) Waiting to run
In OpenSSL 3.5.0, the "quic_transport_parameters" extension set
internally by the QUIC API is cleared on the SSL context switch,
which disables sending QUIC transport parameters if switching to
a different server block on SNI.  See the initial report in [1].

This is fixed post OpenSSL 3.5.0 [2].  The fix is anticipated in
OpenSSL 3.5.1, which has not been released yet.  When building
with OpenSSL 3.5, OpenSSL compat layer is now used by default.
The OpenSSL 3.5 QUIC API support can be switched back using
--with-cc-opt='-DNGX_QUIC_OPENSSL_API=1'.

[1] https://github.com/nginx/nginx/issues/711
[2] https://github.com/openssl/openssl/commit/45bd3c3798
2025-06-23 22:35:09 +04:00
Sergey Kandaurov
cdf7a9c6cb Upstream: fixed reinit request with gRPC and Early Hints.
The gRPC module context has connection specific state, which can be lost
after request reinitialization when it comes to processing early hints.

The fix is to do only a portion of u->reinit_request() implementation
required after processing early hints, now inlined in modules.

Now NGX_HTTP_UPSTREAM_EARLY_HINTS is returned from u->process_header()
for early hints.  When reading a cached response, this code is mapped
to NGX_HTTP_UPSTREAM_INVALID_HEADER to indicate invalid header format.
2025-06-23 20:12:21 +04:00
Andrew Clayton
4eaecc5e8a Use NULL instead of 0 for null pointer constant.
Some checks failed
buildbot / buildbot (push) Has been cancelled
There were a few random places where 0 was being used as a null pointer
constant.

We have a NULL macro for this very purpose, use it.

There is also some interest in actually deprecating the use of 0 as a
null pointer constant in C.

This was found with -Wzero-as-null-pointer-constant which was enabled
for C in GCC 15 (not enabled with Wall or Wextra... yet).

Link: <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117059>
2025-06-21 10:36:45 +04:00
Andrew Clayton
c370ac8a51 Use NGX_CONF_OK in some function return checks.
The functions ngx_http_merge_types() & ngx_conf_merge_path_value()
return either NGX_CONF_OK aka NULL aka ((void *)0) (probably) or
NGX_CONF_ERROR aka ((void *)-1).

They don't return an integer constant which is what NGX_OK aka (0) is.

Lets use the right thing in the function return check.

This was found with -Wzero-as-null-pointer-constant which was enabled
for C in GCC 15 (not enabled with Wall or Wextra... yet).

Link: <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117059>
2025-06-21 10:36:45 +04:00
Sergey Kandaurov
ba917b1360 HTTP/3: indexed field line encoding for "103 Early Hints". 2025-06-21 10:36:28 +04:00
Roman Arutyunyan
662c1dd2a9 Upstream: early hints support.
Some checks failed
buildbot / buildbot (push) Has been cancelled
The change implements processing upstream early hints response in
ngx_http_proxy_module and ngx_http_grpc_module.  A new directive
"early_hints" enables sending early hints to the client.  By default,
sending early hints is disabled.

Example:

    map $http_sec_fetch_mode $early_hints {
        navigate $http2$http3;
    }

    early_hints $early_hints;

    proxy_pass http://example.com;
2025-06-19 10:19:57 +04:00
Roman Arutyunyan
ea001feb10 HTTP/2: added function declaration. 2025-06-19 10:19:57 +04:00
Demi Marie Obenour
9b8e4a1937 Do not support bad whitespace in chunk extensions 2025-06-10 15:19:20 -04:00
Demi Marie Obenour
9950dfbc94 Do not allow trailers to end with bare LF 2025-06-10 15:16:58 -04:00
Demi Marie Obenour
7032a60fa0 HTTP: do not allow status line to end with bare LF
This is consistent with llhttp.
2025-06-10 15:09:54 -04:00
Demi Marie Obenour
bd37faff72 HTTP: do not allow headers to end with a bare LF
This is consistent with Node.js.
2025-06-10 15:09:54 -04:00
Demi Marie Obenour
bb0a2b9de8 HTTP: Allow rejecting leading and trailing whitespace in HTTP2+ fields
All versions of HTTP forbid field (header and trailer) values from
having leading or trailing horizontal whitespace (0x20 and 0x09).  In
HTTP/1.0 and HTTP/1.1, leading and trailing whitespace must be stripped
from the field value before further processing.  In HTTP/2 and HTTP/3,
leading and trailing whitespace must cause the entire message to be
considered malformed.

Willy Tarreau (lead developer of HAProxy) has indicated that there are
clients that actually do send leading and/or trailing whitespace in
HTTP/2 and/or HTTP/3 cookie headers, which is why HAProxy accepts them.
Therefore, the fix is disabled by default and must be enabled with the
reject_leading_trailing_whitespace directive.
2025-06-10 15:09:29 -04:00
Demi Marie Obenour
436282ff74 HTTP: Remove redundant state from chunk parsing
The state machine never returns with state = sw_chunk_data and a size of
zero, nor did it return with state = sw_after_data.
2025-06-10 15:02:24 -04:00
Demi Marie Obenour
626b1d9bba HTTP: Reject trailers involved in framing
These are forbidden by the relevant standards.
2025-06-10 15:02:24 -04:00
Demi Marie Obenour
1c0426c8c0 Forbid malformed HTTP/1.1 trailers
HTTP/1.1 trailers must follow the same syntax as HTTP headers.
2025-06-10 15:02:24 -04:00
Demi Marie Obenour
1be6976866 Reject malformed chunk extensions
This forbids chunk extensions that violate RFC9112, and _only_ these
chunk extensions.  Bad whitespace is permitted, but a bare LF instead of
CRLF is not.
2025-06-10 15:02:24 -04:00
Demi Marie Obenour
0d2c8754ee HTTP: Do not allow request lines to end with bare CR
This is consistent with Node.js.
2025-06-10 15:02:24 -04:00
Demi Marie Obenour
e30ddb7a3b HTTP: Do not allow multiple CRs before LF
This is not permitted by RFC9112.
2025-06-10 15:02:24 -04:00
Demi Marie Obenour
dab8c0e762 HTTP: Do not allow header lines with no colon
RFC9112 does not permit them.
2025-06-10 15:02:24 -04:00
Demi Marie Obenour
98d266924f Proxy: Reject Transfer-Encoding or Content-Length trailers
These are forbidden by the standard, and if they were (invalidly) folded
into a header by downstream code, it would allow HTTP response
splitting.  This is a defense in depth measure.
2025-06-10 15:02:24 -04:00
Demi Marie Obenour
279ae488a4 HTTP: Reject hop-by-hop headers in HTTP/2 and HTTP/3 requests
RFC9113 and RFC9114 both require requests with connection-specific
headers to be treated as malformed, with the exception of "te: trailers".
Reject requests containing them.
2025-06-10 15:02:24 -04:00
Demi Marie Obenour
ae76c64300 HTTP: Reject invalid field values
RFC9110 is clear that the only CTRL character allowed in header values
is HTAB.  Conform to the standard, as Varnish, H2O, and (I suspect)
Hyper do.  This also makes the whitespace-stripping code simpler, as any
character that is less than 0x21 is either whitespace or rejected.
2025-06-10 15:02:24 -04:00
Demi Marie Obenour
b1c4b0757f HTTP: Reject invalid header names
HTTP headers must be an RFC9110 token, so only a subset of characters
are permitted.  RFC9113 and RFC9114 require rejecting invalid header
characters in HTTP/2 and HTTP/3 respectively, so reject them in HTTP/1.0
and HTTP/1.1 for consistency.  This also requires removing the ignore
hack for (presumably ancient) versions of IIS.
2025-06-10 15:02:24 -04:00
Demi Marie Obenour
1e30988516 HTTP: Reject HTTP/2 and HTTP/3 requests with Transfer-Encoding
RFC9113 and RFC9114 are clear that this header cannot be used in these
versions of HTTP, and in other proxies accepting Transfer-Encoding has
led to security vulnerabilities.  NGINX is safe from the vulnerability
because it ignores the header, but this is still wrong.

Fixes: #612
2025-06-10 15:02:24 -04:00
Demi Marie Obenour
17ce4bcfa3 HTTP: Use common header code for v2 and v3
This makes the behavior of HTTP/2 and HTTP/3 much more similar.  In
particular, the HTTP/3 :authority pseudoheader is used to set the Host
header, instead of the virtual server.  This is arguably less correct,
but it is consistent with the existing HTTP/2 behavior and unbreaks
users of PHP-FPM and other FastCGI applications.  In the future, NGINX
could have a config option that caused :authority and Host to be treated
separately in both HTTP/2 and HTTP/3.

Fixes: #587
Fixes: #256
2025-06-10 15:02:24 -04:00
Demi Marie Obenour
c7d26ccc9b HTTP/3: Do not allow invalid pseudo-header fields
RFC9114 requires invalid pseudo-header fields to be rejected, and this
is consistent with HTTP/2.
2025-06-10 15:02:24 -04:00
Demi Marie Obenour
3897c97cc3 Strip leading and trailing whitespace from HTTP field values
Per RFC9110, HTTP field values never contain leading or trailing
whitespace.  Strip all such whitespace from HTTP and HTTP field values.
The HTTP/1.x parser already stripped spaces but didn't strip tabs, so
change the parser to strip tabs as well.  In HTTP/2+, the stripping is
done during validation.  This requires modifying the value.

There are three ways to modify the value:

1. Modify the data in-place with memmove().
2. Move the data pointer to point to after the leading whitespace.
3. Allocate a new buffer and replace the data pointer.

Both HPACK and QPACK decompression make a copy of the data, but some
code might assume that the data pointer of a field value can safely be
passed to ngx_pfree().  Therefore, the first option is chosen.  Existing
code ensures that header values are NUL-terminated, so the stripping
code NUL-pads header values to ensure that the stripped strings have at
least as many terminating NUL bytes as they did before being stripped.

The stripping code has been tested in a standalone program to make sure
that it works correctly, and it correctly strips leading and trailing
whitespace from a variety of strings.  This code has also been tested
with real HTTP/3 requests from Cloudflare's h3i tool.

Fixes: #598
2025-06-10 15:02:24 -04:00
Demi Marie Obenour
80b41e1002 HTTP: Use common header validation function for HTTP/2 and HTTP/3
The header validation required by HTTP/2 and HTTP/3 is identical, so use
a common function for both.  This will make it easier to add additional
validation in the future.  Move the function to ngx_http_parse.c so that
it can share code with the HTTP/1.x parser in the future.

No functional change intended.
2025-06-10 15:02:24 -04:00
Sergey Kandaurov
5b8a5c08ce Core: added support for TCP keepalive parameters on macOS.
Some checks failed
buildbot / buildbot (push) Has been cancelled
The support first appeared in OS X Mavericks 10.9 and documented since
OS X Yosemite 10.10.

It has a subtle implementation difference from other operating systems
in that the TCP_KEEPALIVE socket option (used in place of TCP_KEEPIDLE)
isn't inherited from a listening socket to an accepted socket.

An apparent reason for this behaviour is that it might be preserved for
the sake of backward compatibility.  The TCP_KEEPALIVE socket option is
not inherited since appearance in OS X Panther 10.3, which long predates
two other TCP_KEEPINTVL and TCP_KEEPCNT socket options.

Thanks to Andy Pan for initial work.
2025-05-27 01:59:02 +04:00
Aleksei Bavshin
3d5889a3ee SSL: disabled UI console prompts from worker processes.
Certain providers may attempt to reload the key on the first use after a
fork.  Such attempt would require re-prompting the pin, and this time we
are not able to pass the password callback.

While it is addressable with configuration for a specific provider, it would
be prudent to ensure that no such prompts could block worker processes by
setting the default UI method.

UI_null() first appeared in 1.1.1 along with the OSSL_STORE, so it is safe
to assume the same set of guards.
2025-05-26 06:56:18 -07:00
Aleksei Bavshin
0fdbfc1ff4 SSL: support loading keys via OSSL_STORE.
A new "store:..." prefix for the "ssl_certificate_key" directive allows
loading keys via the OSSL_STORE API.

The change is required to support hardware backed keys in OpenSSL 3.x using
the new "provider(7ossl)" modules, such as "pkcs11-provider".  While the
engine API is present in 3.x, some operating systems (notably, RHEL10)
have already disabled it in their builds of OpenSSL.

Related: https://trac.nginx.org/nginx/ticket/2449
2025-05-26 06:56:18 -07:00
Sergey Kandaurov
6a134dfd48 QUIC: using QUIC API introduced in OpenSSL 3.5.
Similarly to the QUIC API originated in BoringSSL, this API allows
to register custom TLS callbacks for an external QUIC implementation.
See the SSL_set_quic_tls_cbs manual page for details.

Due to a different approach used in OpenSSL 3.5, handling of CRYPTO
frames was streamlined to always write an incoming CRYPTO buffer to
the crypto context.  Using SSL_provide_quic_data(), this results in
transient allocation of chain links and buffers for CRYPTO frames
received in order.  Testing didn't reveal performance degradation of
QUIC handshakes, https://github.com/nginx/nginx/pull/646 provides
specific results.
2025-05-23 15:00:47 +04:00
Sergey Kandaurov
1d4d2f2c96 QUIC: better approach for premature handshake completion.
Using SSL_in_init() to inspect a handshake state was replaced with
SSL_is_init_finished().  This represents a more complete fix to the
BoringSSL issue addressed in 22671b37e.

This provides awareness of the early data handshake state when using
OpenSSL 3.5 TLS callbacks in 0-RTT enabled configurations, which, in
particular, is used to avoid premature completion of the initial TLS
handshake, before required client handshake messages are received.

This is a non-functional change when using BoringSSL.  It supersedes
testing non-positive SSL_do_handshake() results in all supported SSL
libraries, hence simplified.

In preparation for using OpenSSL 3.5 TLS callbacks.
2025-05-23 15:00:47 +04:00
Sergey Kandaurov
bcb9d3fd2c QUIC: ssl_encryption_level_t abstraction layer.
Encryption level values are decoupled from ssl_encryption_level_t,
which is now limited to BoringSSL QUIC callbacks, with mappings
provided.  Although the values match, this provides a technically
safe approach, in particular, to access protection level sized arrays.

In preparation for using OpenSSL 3.5 TLS callbacks.
2025-05-23 15:00:47 +04:00
Sergey Kandaurov
9857578f15 QUIC: factored out SSL_provide_quic_data() to the helper function.
It is now called from ngx_quic_handle_crypto_frame(), prior to proceeding
with the handshake.  With this logic removed, the handshake function is
renamed to ngx_quic_handshake() to better match ngx_ssl_handshake().
2025-05-23 15:00:47 +04:00
Sergey Kandaurov
e561f7dbcf QUIC: defined SSL API macros in a single place.
All definitions now set in ngx_event_quic.h, this includes moving
NGX_QUIC_OPENSSL_COMPAT from autotests to compile time.  Further,
to improve code readability, a new NGX_QUIC_QUICTLS_API macro is
used for QuicTLS that provides old BoringSSL QUIC API.
2025-05-23 15:00:47 +04:00
Sergey Kandaurov
54e6b7cfee QUIC: logging missing mandatory TLS extensions only once.
Previously, they might be logged on every add_handshake_data
callback invocation when using OpenSSL compat layer and processing
coalesced handshake messages.

Further, the ALPN error message is adjusted to signal the missing
extension.  Possible reasons were previously narrowed down with
ebb6f7d65 changes in the ALPN callback that is invoked earlier in
the handshake.
2025-05-23 15:00:47 +04:00
Sergey Kandaurov
5d7fd4a7e3 QUIC: reset qc->error to zero again.
Following the previous change that removed posting a close event
in OpenSSL compat layer, now ngx_quic_close_connection() is always
called on error path with either NGX_ERROR or qc->error set.

This allows to remove a special value -1 served as a missing error,
which simplifies the code.  Partially reverts d3fb12d77.

Also, this improves handling of the draining connection state, which
consists of posting a close event with NGX_OK and no qc->error set,
where it was previously converted to NGX_QUIC_ERR_INTERNAL_ERROR.
Notably, this is rather a cosmetic fix, because drained connections
do not send any packets including CONNECTION_CLOSE, and qc->error
is not otherwise used.
2025-05-23 15:00:47 +04:00