Commit Graph

16542 Commits

Author SHA1 Message Date
Amaury Denoyelle
bb56530470 MINOR: h3: set CS_FL_NOT_FIRST
When creating a new conn-stream on H3 HEADERS parsing, the flag
CS_FL_NOT_FIRST must be set. This is identical to the mux-h2.
2022-02-15 17:10:51 +01:00
Amaury Denoyelle
eb53e5baa1 MINOR: mux-quic: set EOS on rcv_buf
Flags EOI/EOS must be set on conn-stream when transfering the last data
of a stream in rcv_buf. This is activated if qcs HTX buffer has the EOM
flag and has been fully transfered.
2022-02-15 17:10:51 +01:00
Amaury Denoyelle
9a327a7c3f MINOR: mux-quic: implement rcv_buf
Implement the stream rcv_buf operation on QUIC mux.

A new buffer is stored in qcs structure named app_buf. This new buffer
will contains HTX and will be filled for example on H3 DATA frame
parsing.

The rcv_buf operation transfer as much as possible data from the HTX
from app_buf to the conn-stream buffer. This is mainly identical to
mux-h2. This is required to support HTTP POST data.
2022-02-15 17:10:51 +01:00
Amaury Denoyelle
95b93a3a93 MINOR: h3: set properly HTX EOM/BODYLESS on HEADERS parsing
Adjust the method to detect that a H3 HEADERS frame is the last one of
the stream. If this is true, the flags EOM and BODYLESS must be set on
the HTX message.
2022-02-15 17:08:48 +01:00
Amaury Denoyelle
a04724af29 MINOR: h3: add documentation on h3_decode_qcs
Specify the purpose of the fin argument on h3_decode_qcs.
2022-02-15 17:08:32 +01:00
Amaury Denoyelle
ffafb3d2c2 MINOR: h3: remove transfer-encoding header
According to HTTP/3 specification, transfer-encoding header must not be
used in HTTP/3 messages. Remove it when converting HTX responses to
HTTP/3.
2022-02-15 17:08:22 +01:00
Amaury Denoyelle
4ac6d37333 BUG/MINOR: h3: fix the header length for QPACK decoding
Pass the H3 frame length to QPACK decoding instead of the length of the
whole buffer.

Without this fix, if there is multiple H3 frames starting with a
HEADERS, QPACK decoding will be erroneously applied over all of them,
most probably leading to a decoding error.
2022-02-15 17:06:22 +01:00
Amaury Denoyelle
6a2c2f4910 BUG/MINOR: quic: fix FIN stream signaling
If the last frame is not entirely copied and must be buffered, FIN
must not be signaled to the upper layer.

This might fix a rare bug which could cause the request channel to be
closed too early leading to an incomplete request.
2022-02-15 17:01:14 +01:00
Amaury Denoyelle
ab9cec7ce1 MINOR: qpack: fix typo in trace
hanme -> hname
2022-02-15 11:08:17 +01:00
Amaury Denoyelle
4af6595d41 BUG/MEDIUM: quic: fix crash on CC if mux not present
If a CONNECTION_CLOSE is received during handshake or after mux release,
a segfault happens due to invalid dereferencement of qc->qcc. Check
mux_state first to prevent this.
2022-02-15 11:08:17 +01:00
Amaury Denoyelle
8524f0f779 MINOR: quic: use a global dghlrs for each thread
Move the QUIC datagram handlers oustide of the receivers. Use a global
handler per-thread which is allocated on post-config. Implement a free
function on process deinit to avoid a memory leak.
2022-02-15 10:13:20 +01:00
Willy Tarreau
6c8babf6c4 BUG/MAJOR: sched: prevent rare concurrent wakeup of multi-threaded tasks
Since the relaxation of the run-queue locks in 2.0 there has been a
very small but existing race between expired tasks and running tasks:
a task might be expiring and being woken up at the same time, on
different threads. This is protected against via the TASK_QUEUED and
TASK_RUNNING flags, but just after the task finishes executing, it
releases it TASK_RUNNING bit an only then it may go to task_queue().
This one will do nothing if the task's ->expire field is zero, but
if the field turns to zero between this test and the call to
__task_queue() then three things may happen:
  - the task may remain in the WQ until the 24 next days if it's in
    the future;
  - the task may prevent any other task after it from expiring during
    the 24 next days once it's queued
  - if DEBUG_STRICT is set on 2.4 and above, an abort may happen
  - since 2.2, if the task got killed in between, then we may
    even requeue a freed task, causing random behaviour next time
    it's found there, or possibly corrupting the tree if it gets
    reinserted later.

The peers code is one call path that easily reproduces the case with
the ->expire field being reset, because it starts by setting it to
TICK_ETERNITY as the first thing when entering the task handler. But
other code parts also use multi-threaded tasks and rightfully expect
to be able to touch their expire field without causing trouble. No
trivial code path was found that would destroy such a shared task at
runtime, which already limits the risks.

This must be backported to 2.0.
2022-02-14 20:10:43 +01:00
Willy Tarreau
27c8da1fd5 DEBUG: pools: replace the link pointer with the caller's address on pool_free()
Along recent evolutions of the pools, we've lost the ability to reliably
detect double-frees because while in the past the same pointer was being
used to chain the objects in the cache and to store the pool's address,
since 2.0 they're different so the pool's address is never overwritten on
free() and a double-free will rarely be detected.

This patch sets the caller's return address there. It can never be equal
to a pool's address and will help guess what was the previous call path.
It will not work on exotic architectures nor with very old compilers but
these are not the environments where we're trying to get detailed bug
reports, and this is not done by default anyway so we don't care about
this limitation. Note that depending on the inlining status of the
function, the result may differ but that's no big deal either.

A test by placing a double free of an appctx inside the release handler
itself successfully reported the trouble during appctx_free() and showed
that the return address was in stream_int_shutw_applet() (this one calls
the release handler).
2022-02-14 20:10:43 +01:00
Willy Tarreau
49bb5d4268 DEBUG: pools: let's add reverse mapping from cache heads to thread and pool
During global eviction we're visiting nodes from the LRU tail and we
determine their pool cache head and their pool. In order to make sure
we never mess up, let's add some backwards pointer to the thread number
and pool from the pool_cache_head. It's 64-byte aligned anyway so we're
not wasting space and it helps for debugging and will prevent memory
corruption the earliest possible.
2022-02-14 20:10:43 +01:00
Willy Tarreau
e2830addda DEBUG: pools: add extra sanity checks when picking objects from a local cache
These few checks are added to make sure we never try to pick an object from
an empty list, which would have a devastating effect.
2022-02-14 20:10:43 +01:00
Willy Tarreau
ceabc5ca8c CLEANUP: pools: don't needlessly set a call mark during refilling of caches
When refilling caches from the shared cache, it's pointless to set the
pointer to the local pool since it may be overwritten immediately after
by the LIST_INSERT(). This is a leftover from the pre-2.4 code in fact.
It didn't hurt, though.
2022-02-14 20:10:43 +01:00
Willy Tarreau
c895c441c7 BUG/MINOR: pools: always flush pools about to be destroyed
When destroying a pool (e.g. at exit or when resizing buffers), it's
important to try to free all their local objects otherwise we can leave
some in the cache. This is particularly visible when changing "bufsize",
because "show pools" will then show two "trash" pools, one of which
contains a single object in cache (which is fortunately not reachable).
In all cases this happens while single-threaded so that's easy to do,
we just have to do it on the current thread.

The easiest way to do this is to pass an extra argument to function
pool_evict_from_local_cache() to force a full flush instead of a
partial one.

This can probably be backported to about all branches where this
applies, but at least 2.4 needs it.
2022-02-14 20:10:43 +01:00
Willy Tarreau
b5ba09ed58 BUG/MEDIUM: pools: ensure items are always large enough for the pool_cache_item
With the introduction of DEBUG_POOL_TRACING in 2.6-dev with commit
add43fa43 ("DEBUG: pools: add new build option DEBUG_POOL_TRACING"), small
pools might be too short to store both the pool_cache_item struct and the
caller location, resulting in memory corruption and crashes when this debug
option is used.

What happens here is that the way the size is calculated is by considering
that the POOL_EXTRA part is only used while the object is in use, but this
is not true anymore for the caller's pointer which must absolutely be placed
after the pool_cache_item.

This patch makes sure that the caller part will always start after the
pool_cache_item and that the allocation will always be sufficent. This is
only tagged medium because the debug option is new and unlikely to be used
unless requested by a developer.

No backport is needed.
2022-02-14 20:10:43 +01:00
Frédéric Lécaille
547aa0e95e MINOR: quic: Useless statement in quic_crypto_data_cpy()
This should fix Coverity CID 375057 in GH #1526 where a useless assignment
was detected.
2022-02-14 15:20:54 +01:00
Frédéric Lécaille
c0b481f87b MINOR: quic: Possible memleak in qc_new_conn()
This should fix Coverity CID 375047 in GH #1536 where <buf_area> could leak because
not always freed by by quic_conn_drop(), especially when not stored in <qc> variable.
2022-02-14 15:20:54 +01:00
Frédéric Lécaille
225c31fc9f CLEANUP: h3: Unreachable target in h3_uqs_init()
This should fix Coverity CID 375045 in GH #1536 which detects a no more
use "err" target in h3_uqs_init()
2022-02-14 15:20:54 +01:00
Frédéric Lécaille
6842485a84 MINOR: quic: Possible overflow in qpack_get_varint()
This should fix CID 375051 in GH 1536 where a signed integer expression (1 << bit)
which could overflow was compared to a uint64_t.
2022-02-14 15:20:54 +01:00
Frédéric Lécaille
ce2ecc9643 MINOR: quic: Potential overflow expression in qc_parse_frm()
This should fix Coverity CID 375056 where an unsigned char was used
to store a 32bit mask.
2022-02-14 15:20:54 +01:00
Frédéric Lécaille
439c464250 MINOR: quic: EINTR error ignored
This should fix Coverity CID 375050 in GH #1536 where EINTR errno was ignored due
to wrong do...while() loop usage.
2022-02-14 15:20:54 +01:00
Frédéric Lécaille
3916ca197e MINOR: quic: Variable used before being checked in ha_quic_add_handshake_data()
This should fix Coverity CID 375058 in GH issue #1536
2022-02-14 15:20:54 +01:00
Frédéric Lécaille
83cd51e87a MINOR: quic: Remove an RX buffer useless lock
This lock is no more useful: the RX buffer for a connection is always handled
by the same thread.
2022-02-14 15:20:54 +01:00
Remi Tricot-Le Breton
88c5695c67 MINOR: ssl: Remove calls to SSL_CTX_set_tmp_dh_callback on OpenSSLv3
The SSL_CTX_set_tmp_dh_callback function was marked as deprecated in
OpenSSLv3 so this patch replaces this callback mechanism by a direct set
of DH parameters during init.
2022-02-14 10:07:14 +01:00
Remi Tricot-Le Breton
c76c3c4e59 MEDIUM: ssl: Replace all DH objects by EVP_PKEY on OpenSSLv3 (via HASSL_DH type)
DH structure is a low-level one that should not be used anymore with
OpenSSLv3. All functions working on DH were marked as deprecated and
this patch replaces the ones we used with new APIs recommended in
OpenSSLv3, be it in the migration guide or the multiple new manpages
they created.
This patch replaces all mentions of the DH type by the HASSL_DH one,
which will be replaced by EVP_PKEY with OpenSSLv3 and will remain DH on
older versions. It also uses all the newly created helper functions that
enable for instance to load DH parameters from a file into an EVP_PKEY,
or to set DH parameters into an SSL_CTX for use in a DHE negotiation.

The following deprecated functions will effectively disappear when
building with OpenSSLv3 : DH_set0_pqg, PEM_read_bio_DHparams, DH_new,
DH_free, DH_up_ref, SSL_CTX_set_tmp_dh.
2022-02-14 10:07:14 +01:00
Remi Tricot-Le Breton
55d7e782ee MINOR: ssl: Set default dh size to 2048
Starting from OpenSSLv3, we won't rely on the
SSL_CTX_set_tmp_dh_callback mechanism so we will need to know the DH
size we want to use during init. In order for the default DH param size
to be used when no RSA or DSA private key can be found for a given bind
line, we will need to know the default size we want to use (which was
not possible the way the code was built, since the global default dh
size was set too late.
2022-02-14 10:07:14 +01:00
Remi Tricot-Le Breton
bed72631f9 MINOR: ssl: Build local DH of right size when needed
The current way the local DH structures are built relies on the fact
that the ssl_get_tmp_dh function would only be called as a callback
during a DHE negotiation, so after all the SSL contexts are built and
the init is over. With OpenSSLv3, this function will now be called
during init, so before those objects are curretly built.
This patch ensures that when calling ssl_get_tmp_dh and trying to use
one of or hard-coded DH parameters, it will be created if it did not
exist yet.
The current DH parameter creation is also kept so that with versions
before OpenSSLv3 we don't end up creating this DH object during a
handshake.
2022-02-14 10:07:14 +01:00
Remi Tricot-Le Breton
7f6425a130 MINOR: ssl: Add ssl_new_dh_fromdata helper function
Starting from OpenSSLv3, the DH_set0_pqg function is deprecated and the
use of DH objects directly is advised against so this new helper
function will be used to convert our hard-coded DH parameters into an
EVP_PKEY. It relies on the new OSSL_PARAM mechanism, as described in the
EVP_PKEY-DH manpage.
2022-02-14 10:07:14 +01:00
Remi Tricot-Le Breton
5f17930572 MINOR: ssl: Add ssl_sock_set_tmp_dh_from_pkey helper function
This helper function will only be used with OpenSSLv3. It simply sets in
an SSL_CTX a set of DH parameters of the same size as a certificate's
private key. This logic is the same as the one used with older versions,
it simply relies on new APIs.
If no pkey can be found the SSL_CTX_set_dh_auto function wll be called,
making the SSL_CTX rely on DH parameters provided by OpenSSL in case of
DHE negotiation.
2022-02-14 10:07:14 +01:00
Remi Tricot-Le Breton
846eda91ba MINOR: ssl: Add ssl_sock_set_tmp_dh helper function
Starting from OpenSSLv3, the SSL_CTX_set_tmp_dh function is deprecated
and it should be replaced by SSL_CTX_set0_tmp_dh_pkey, which takes an
EVP_PKEY instead of a DH parameter. Since this function is new to
OpenSSLv3 and its use requires an extra EVP_PKEY_up_ref call, we will
keep the two versions side by side, otherwise it would require to get
rid of all DH references in older OpenSSL versions as well.
This helper function is not used yet so this commit should be strictly
iso-functional, regardless of the OpenSSL version.
2022-02-14 10:07:14 +01:00
Remi Tricot-Le Breton
292a88ce94 MINOR: ssl: Factorize ssl_get_tmp_dh and append a cbk to its name
In the upcoming OpenSSLv3 specific patches, we will make use of the
newly created ssl_get_tmp_dh that returns an EVP_PKEY containing DH
parameters of the same size as a bind line's RSA or DSA private key.
The previously named ssl_get_tmp_dh function was renamed
ssl_get_tmp_dh_cbk because it is only used as a callback passed to
OpenSSL through SSL_CTX_set_tmp_dh_callback calls.
2022-02-14 10:07:14 +01:00
Remi Tricot-Le Breton
09ebb3359a MINOR: ssl: Add ssl_sock_get_dh_from_bio helper function
This new function makes use of the new OpenSSLv3 APIs that should be
used to load DH parameters from a file (or a BIO in this case) and that
should replace the deprecated PEM_read_bio_DHparams function.
Note that this function returns an EVP_PKEY when using OpenSSLv3 since
they now advise against using low level structures such as DH ones.
This helper function is not used yet so this commit should be stricly
iso-functional, regardless of the OpenSSL version.
2022-02-14 10:07:14 +01:00
Remi Tricot-Le Breton
956f3aea03 MINOR: ssl: Create HASSL_DH wrapper structure
The DH mechanism relies on DH objects that are low-level structures that
should not be used anymore starting from OpenSSLv3. With the newer
OpenSSL version, we should only use higher level EVP_PKEY objects.
Since enforcing this new logic to older versions of OpenSSL could be
dangerous (or plain impossible), we will keeptwo versions of the code
when required.
The HASSL_DH define will allow to unify some of the functions that were
created for DH use without having to add too many duplicated blocks of
code depending on the OpenSSL version.
2022-02-14 10:07:14 +01:00
Remi Tricot-Le Breton
17b7384f82 REGTESTS: ssl: Add tests for DH related options
This new test checks that the DH-related mechanism works, be it through
specific DH parameters included in a bind line's certificate or by using
the ssl-dh-param-file or tune.ssl.default-dh-param global options.
2022-02-14 10:07:14 +01:00
Remi Tricot-Le Breton
78a36e3344 MINOR: ssl: Remove call to ERR_load_SSL_strings with OpenSSLv3
Starting from OpenSSLv3, error strings are loaded automatically so
ERR_load_SSL_strings is not needed anymore and was marked as deprecated.
2022-02-14 10:07:14 +01:00
Remi Tricot-Le Breton
1effd9aa09 MINOR: ssl: Remove call to ERR_func_error_string with OpenSSLv3
ERR_func_error_string does not return anything anymore with OpenSSLv3,
it can be replaced by ERR_peek_error_func which did not exist on
previous versions.
2022-02-14 10:07:14 +01:00
William Lallemand
7b820a6191 BUG/MINOR: mworker: does not erase the pidfile upon reload
When started in master-worker mode combined with daemon mode, HAProxy
will open() with O_TRUNC the pidfile when switching to wait mode.

In 2.5, it happens  everytime after trying to load the configuration,
since we switch to wait mode.

In previous version this happens upon a failure of the configuration
loading.

Fixes bug #1545.

Must be backported in every supported branches.
2022-02-14 09:28:13 +01:00
Ilya Shipitsin
6fed59c7c1 CI: enable QUIC for Coverity scan 2022-02-12 08:06:34 +01:00
Amaury Denoyelle
58a7704d54 MINOR: quic: take out xprt snd_buf operation
Rename quic_conn_to_buf to qc_snd_buf and remove it from xprt ops. This
is done to reflect the true usage of this function which is only a
wrapper around sendto but cannot be called by the upper layer.

qc_snd_buf is moved in quic-sock because to mark its link with
quic_sock_fd_iocb which is the recvfrom counterpart.
2022-02-09 15:57:46 +01:00
Amaury Denoyelle
80bd837aaf MINOR: quic: remove unused xprt rcv_buf operation
rcv_buf and the implement quic_conn_to_buf is not used. recvfrom instead
is called on the listener polling task via quic_sock_fd_iocb.
2022-02-09 15:57:41 +01:00
Amaury Denoyelle
f6dcbce53e MINOR: quic: rename local tid variable
Rename a local variable tid to cid_tid. This ensures there is no
confusion with the global tid. It is now more explicit that we are
manipulating a quic datagram handlers from another thread in
quic_lstnr_dgram_dispatch.
2022-02-09 15:05:23 +01:00
Amaury Denoyelle
59e0b1f44c MINOR: mux-quic: remove quic_transport_params_update
This function is unused.
2022-02-09 15:05:23 +01:00
Amaury Denoyelle
b78805488b MINOR: h3: hardcode the stream id of control stream
Use the value of 0x3 for the stream-id of H3 control-stream. As a
consequence, qcs_get_next_id is now unused and is thus removed.
2022-02-09 15:05:23 +01:00
Remi Tricot-Le Breton
c9414e25c4 MINOR: ssl: Remove call to HMAC_Init_ex with OpenSSLv3
HMAC_Init_ex being a function that acts on a low-level HMAC_CTX
structure was marked as deprecated in OpenSSLv3.
This patch replaces this call by EVP_MAC_CTX_set_params, as advised in
the migration_guide, and uses the new OSSL_PARAM mechanism to configure
the MAC context, as described in the EVP_MAC and EVP_MAC-HMAC manpages.
2022-02-09 12:11:31 +01:00
Remi Tricot-Le Breton
8ea1f5f6cd MINOR: ssl: Remove call to SSL_CTX_set_tlsext_ticket_key_cb with OpenSSLv3
SSL_CTX_set_tlsext_ticket_key_cb was deprecated on OpenSSLv3 because it
uses an HMAC_pointer which is deprecated as well. According to the v3's
manpage it should be replaced by SSL_CTX_set_tlsext_ticket_key_evp_cb
which uses a EVP_MAC_CTX pointer.
This new callback was introduced in OpenSSLv3 so we need to keep the two
calls in the source base and to split the usage depending on the OpenSSL
version.
2022-02-09 12:11:31 +01:00
Remi Tricot-Le Breton
3f269bb370 REGTESTS: ssl: Add test for "generate-certificates" SSL option
The 'generate-certificates' bind line option that allows to create
server certificates on-the-fly for newly used SNIs was not tested yet.
2022-02-09 12:10:32 +01:00
Remi Tricot-Le Breton
c11e7e1d94 MINOR: ssl: Remove EC_KEY related calls when creating a certificate
In the context of the 'generate-certificates' bind line option, if an
'ecdhe' option is present on the bind line as well, we use the
SSL_CTX_set_tmp_ecdh function which was marked as deprecated in
OpenSSLv3. As advised in the SSL_CTX_set_tmp_ecdh manpage, this function
should be replaced by the SSL_CTX_set1_groups one (or the
SSL_CTX_set1_curves one in our case which does the same but existed on
older OpenSSL versions as well).

The ECDHE behaviour with OpenSSL 1.0.2 is not the same when using the
SSL_CTX_set1_curves function as the one we have on newer versions.
Instead of looking for a code that would work exactly the same
regardless of the OpenSSL version, we will keep the original code on
1.0.2 and use newer APIs for other versions.

This patch should be strictly isofunctional.
2022-02-09 11:15:44 +01:00