Commit Graph

16614 Commits

Author SHA1 Message Date
Andrew McDermott
bfb15ab34e BUG/MAJOR: http/htx: prevent unbounded loop in http_manage_server_side_cookies
Ensure calls to http_find_header() terminate. If a "Set-Cookie2"
header is found then the while(1) loop in
http_manage_server_side_cookies() will never terminate, resulting in
the watchdog firing and the process terminating via SIGABRT.

The while(1) loop becomes unbounded because an unmatched call to
http_find_header("Set-Cookie") will leave ctx->blk=NULL. Subsequent
calls to check for "Set-Cookie2" will now enumerate from the beginning
of all the blocks and will once again match on subsequent
passes (assuming a match first time around), hence the loop becoming
unbounded.

This issue was introduced with HTX and this fix should be backported
to all versions supporting HTX.

Many thanks to Grant Spence (gspence@redhat.com) for working through
this issue with me.
2022-02-16 14:42:13 +01:00
Amaury Denoyelle
1d5fdc526b MINOR: h3: remove unused return value on decode_qcs
This should fix 1470806 coverity report from github issue #1550.
2022-02-16 14:37:56 +01:00
William Lallemand
de6ecc3ace BUG/MINOR: httpclient/cli: display junk characters in vsn
ist are not ended by '\0', leading to junk characters being displayed
when using %s for printing the HTTP start line.

Fix the issue by replacing %s by %.*s + istlen.

Must be backported in 2.5.
2022-02-16 11:37:02 +01:00
Remi Tricot-Le Breton
d544d33e10 BUG/MINOR: jwt: Memory leak if same key is used in multiple jwt_verify calls
If the same filename was specified in multiple calls of the jwt_verify
converter, we would have parsed the contents of the file every time it
was used instead of checking if the entry already existed in the tree.
This lead to memory leaks because we would not insert the duplicated
entry and we would not free it (as well as the EVP_PKEY it referenced).
We now check the return value of ebst_insert and free the current entry
if it is a duplicate of an existing entry.
The order in which the tree insert and the pkey parsing happen was also
switched in order to avoid parsing key files in case of duplicates.

Should be backported to 2.5.
2022-02-15 20:08:20 +01:00
Remi Tricot-Le Breton
2b5a655946 BUG/MINOR: jwt: Missing pkey free during cleanup
When emptying the jwt_cert_tree during deinit, the entries are freed but
not the EVP_PKEY reference they kept, leading in a memory leak.

Should be backported in 2.5.
2022-02-15 20:08:20 +01:00
Remi Tricot-Le Breton
4930c6c869 BUG/MINOR: jwt: Double free in deinit function
The node pointer was not moving properly along the jwt_cert_tree during
the deinit which ended in a double free during cleanup (or when checking
a configuration that used the jwt_verify converter with an explicit
certificate specified).

This patch fixes GitHub issue #1533.
It should be backported to 2.5.
2022-02-15 20:08:20 +01:00
Amaury Denoyelle
31e4f6e149 MINOR: h3: report error on HEADERS/DATA parsing
Inspect return code of HEADERS/DATA parsing functions and use a BUG_ON
to signal an error. The stream should be closed to handle the error
in a more clean fashion.
2022-02-15 17:33:21 +01:00
Frédéric Lécaille
71f3abbb52 MINOR: quic: Move quic_rxbuf_pool pool out of xprt part
This pool could be confuse with that of the RX buffer pool for the connection
(quic_conn_rxbuf).
2022-02-15 17:33:21 +01:00
Frédéric Lécaille
53c7d8db56 MINOR: quic: Do not retransmit too much packets.
We retranmist at most one datagram and possibly one more with only PING frame
as ack-eliciting frame.
2022-02-15 17:33:21 +01:00
Frédéric Lécaille
0c80e69470 MINOR: quic: Possible frame parsers array overrun
This should fix CID 1469663 for GH #1546.
2022-02-15 17:33:21 +01:00
Frédéric Lécaille
59509b5187 MINOR: quic: Non checked returned value for cs_new() in h3_decode_qcs()
This should fix CID 1469664 for GH #1546
2022-02-15 17:33:21 +01:00
Frédéric Lécaille
3c08cb4948 MINOR: h3: Dead code in h3_uqs_init()
This should fix CID 1469657 for GH #1546.
2022-02-15 17:23:44 +01:00
Frédéric Lécaille
1e1fb5db45 MINOR: quic: Non checked returned value for cs_new() in hq_interop_decode_qcs()
This should fix CID 1469657 for GH #1546
2022-02-15 17:23:44 +01:00
Frédéric Lécaille
498e992c1c MINOR: quic: Useless test in quic_lstnr_dghdlr()
This statement is useless. This should fix CID 1469651 for GH #1546.
2022-02-15 17:23:44 +01:00
Frédéric Lécaille
e1c3546efa MINOR: quic: Avoid warning about NULL pointer dereferences
This is the same fixe as for this commit:
    "BUILD: tree-wide: avoid warnings caused by redundant checks of obj_types"
Should fix CID 1469649 for GH #1546
2022-02-15 17:23:44 +01:00
Frédéric Lécaille
ee4508da4f MINOR: quic: ha_quic_set_encryption_secrets without server specific code
Remove this server specific code section. It is useless, not tested. Furthermore
this is really not the good place to retrieve the peer transport parameters.
2022-02-15 17:23:44 +01:00
Frédéric Lécaille
16de9f7dbf MINOR: quic: Code never reached in qc_ssl_sess_init()
There was a remaining useless statement in this code block.
This fixes CID 1469648 for GH #1546
2022-02-15 17:23:44 +01:00
Frédéric Lécaille
21db6f962b MINOR: quic: Wrong loss delay computation
I really do not know where does this statement come from even after having
checked several drafts.
2022-02-15 17:23:44 +01:00
Frédéric Lécaille
eca47d9a8a MINOR: quic: Wrong smoothed rtt initialization
In ->srtt we store 8*srtt to ease the srtt computations with this formula:
    srtt = 7/8 * srtt + 1/8 * adjusted_rtt
But its initialization was wrong.
2022-02-15 17:23:44 +01:00
Amaury Denoyelle
91379f79f8 MINOR: h3: implement DATA parsing
Add a new function h3_data_to_htx. This function is used to parse a H3
DATA frame and copy it in the mux stream HTX buffer. This is required to
support HTTP POST data.

Note that partial transfers if the HTX buffer is fulled is not properly
handle. This causes large DATA transfer to fail at the moment.
2022-02-15 17:17:00 +01:00
Amaury Denoyelle
7b0f1220d4 MINOR: h3: extract HEADERS parsing in a dedicated function
Move the HEADERS parsing code outside of generic h3_decode_qcs to a new
dedicated function h3_headers_to_htx. The benefit will be visible when
other H3 frames parsing will be implemented such as DATA.
2022-02-15 17:12:27 +01:00
Amaury Denoyelle
0484f92656 MINOR: h3: report frames bigger than rx buffer
If a frame is bigger than the qcs buffer, it can not be parsed at the
moment. Add a TODO comment to signal that a fix is required.
2022-02-15 17:11:59 +01:00
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