]> git.ipfire.org Git - thirdparty/haproxy.git/log
thirdparty/haproxy.git
12 months agoBUG/MINOR: jwt: don't try to load files with HMAC algorithm
William Lallemand [Wed, 3 Jul 2024 10:35:50 +0000 (12:35 +0200)] 
BUG/MINOR: jwt: don't try to load files with HMAC algorithm

When trying to use a HMAC algorithm (HS256, HS384, HS512) the
sample_conv_jwt_verify_check() function of the converter tries to load a
file even if it is only supposed to contain a secret instead of a path.

When using lua, the check function is called at runtime so it even tries
to load file at each call... This fixes the issue for HMAC algorithm
but this is still a problem with the other algorithms, since we don't
have a way of pre-loading files before the call.

Another solution must be found to prevent disk IO with lua using other
algorithms.

Must be backported as far as 2.6.

12 months agoBUG/MEDIUM: server: fix race on server_atomic_sync()
Amaury Denoyelle [Tue, 2 Jul 2024 16:14:57 +0000 (18:14 +0200)] 
BUG/MEDIUM: server: fix race on server_atomic_sync()

The following patch fixes a race condition during server addr/port
update :
  cd994407a9545a8d84e410dc0cc18c30966b70d8
  BUG/MAJOR: server/addr: fix a race during server addr:svc_port updates

The new update mechanism is implemented via an event update. It uses
thread isolation to guarantee that no other thread is accessing server
addr/port. Furthermore, to ensure server instance is not deleted just
before the event handler, server instance is lookup via its ID in proxy
tree.

However, thread isolation is only entered after server lookup. This
leaves a tiny race condition as the thread will be marked as harmless
and a concurrent thread can delete the server in the meantime. This
causes server_atomic_sync() to manipulated a deleted server instance to
reinsert it in used_server_addr backend tree. This can cause a segfault
during this operation or possibly on a future used_server_addr tree
access.

This issue was detected by criteo. Several backtraces were retrieved,
each related to server addr_node insert or delete operation, either in
srv_set_addr_desc(), or add/delete dynamic server handlers.

To fix this, simply extend thread isolation section to start it before
server lookup. This ensures that once retrieved the server cannot be
deleted until its addr/port are updated. To ensure this issue won't
happen anymore, a new BUG_ON() is added in srv_set_addr_desc().

Also note that ebpt_delete() is now called every time on delete handler
as this is a safe idempotent operation.

To reproduce these crashes, a script was executed to add then remove
different servers every second. In parallel, the following CLI command
was issued repeatdly without any delay to force multiple update on
servers port :

  set server <srv> addr 0.0.0.0 port $((1024 + RANDOM % 1024))

This must be backported at least up to 3.0. If above mentionned patch
has been selected for previous version, this commit must also be
backported on them.

12 months agoDOC: configuration: more details about the master-worker mode
William Lallemand [Tue, 2 Jul 2024 16:23:34 +0000 (18:23 +0200)] 
DOC: configuration: more details about the master-worker mode

Add more details about the master-worker mode in the "master-worker"
global keyword.

Should fix issue #2198.

12 months agoBUG/MEDIUM: hlua/cli: Fix lua CLI commands to work with applet's buffers
Christopher Faulet [Mon, 1 Jul 2024 12:33:59 +0000 (14:33 +0200)] 
BUG/MEDIUM: hlua/cli: Fix lua CLI commands to work with applet's buffers

In 3.0, the CLI applet was rewritten to use its own buffers. However, the
lua part, used to register CLI commands at runtime, was not updated
accordingly. It means the lua CLI commands still try to write in the channel
buffers. This is of course totally unexepected and not supported. Because of
this bug, the applet hangs intead of returning the command result.

The registration of lua CLI commands relies on the lua TCP applets. So the
send and receive functions were fixed to use the applet's buffer when it is
required and still use the channel buffers otherwies. This way, other lua
TCP applets can still run on the legacy mode, without the applet's buffers.

This patch must be backported to 3.0.

12 months agoDOC: configuration: add details about crt-store in bind "crt" keyword
William Lallemand [Mon, 1 Jul 2024 10:17:00 +0000 (12:17 +0200)] 
DOC: configuration: add details about crt-store in bind "crt" keyword

Add some details about the certificate storage cache system in the "crt"
bind keyword.

This should be backported to 3.0. Fix issue #2618.

12 months agoBUG/MINOR: promex: Remove Help prefix repeated twice for each metric
Christopher Faulet [Mon, 1 Jul 2024 08:33:03 +0000 (10:33 +0200)] 
BUG/MINOR: promex: Remove Help prefix repeated twice for each metric

When the support for modules was added, the function producing the #HELP
line of each metric was refactored. Since then, the prefix "#HELP
<metric-name>" is printed twice because a code block was not removed. It is
now fixed.

This patch must be backported to 3.0.

12 months agoBUG/MEDIUM: quic: fix possible exit from qc_check_dcid() without unlocking
Willy Tarreau [Sun, 30 Jun 2024 04:23:30 +0000 (06:23 +0200)] 
BUG/MEDIUM: quic: fix possible exit from qc_check_dcid() without unlocking

Locking of the CID tree was extended in qc_check_dcid() by recent commit
05f59a5 ("BUG/MINOR: quic: fix race condition in qc_check_dcid()") but
there was a direct return from the middle of the function which was not
covered by the unlock, resulting in the function keeping the lock on
success return.

Let's just remove this return and replace it with a variable to merge all
exit paths.

This must be backported wherever the fix above is backported.

12 months agoBUG/MINOR: quic: Wrong datagram building when probing.
Frederic Lecaille [Wed, 26 Jun 2024 14:06:53 +0000 (16:06 +0200)] 
BUG/MINOR: quic: Wrong datagram building when probing.

This issue was revealed by chacha20 interop test which very often fails with
ngtcp2 as client. This was due to the fact that 2 application level packets could
be coalesced into the same datagram as revealed by such a capture:

Frame 380: 255 bytes on wire (2040 bits), 255 bytes captured (2040 bits)
Point-to-Point Protocol
Internet Protocol Version 4, Src: 193.167.100.100, Dst: 193.167.0.100
User Datagram Protocol
QUIC IETF
    QUIC Connection information
        [Connection Number: 0]
    [Packet Length: 187]
    QUIC Short Header DCID=ec523fe99840f9c17c868a88d649147814 PKN=333
        0... .... = Header Form: Short Header (0)
        .1.. .... = Fixed Bit: True
        ..0. .... = Spin Bit: False
        [...0 0... = Reserved: 0]
        [.... .0.. = Key Phase Bit: False]
        [.... ..00 = Packet Number Length: 1 bytes (0)]
        Destination Connection ID: ec523fe99840f9c17c868a88d649147814
        [Packet Number: 333]
        Protected Payload […]: 43537d43a3c83e47db6891bd6a4fd7d7fa31941badcb87a540e843341d6a5e493ed4c3f6e6bbff094804ee0ab06830dc1a1bbf52ace4323d2e4f6e0bd4eea73df0721d2949d05a058d3afb974e814494ebf44d1375b0e7f1fd5bcf634cf32ef9a9b4018758a49d39a24c40
    STREAM id=0 fin=0 off=294768 len=144 dir=Bidirectional origin=Client-initiated
        Frame Type: STREAM (0x000000000000000e)
            .... ...0 = Fin: False
            .... ..1. = Len(gth): True
            .... .1.. = Off(set): True
        Stream ID: 0
            .... .... .... .... .... .... .... .... .... .... .... .... .... .... .... ...0 = Stream initiator: Client-initiated (0)
            .... .... .... .... .... .... .... .... .... .... .... .... .... .... .... ..0. = Stream direction: Bidirectional (0)
        Offset: 294768
        Length: 144
        Stream Data […]: 63eef6ccee0d2ab602db3682d0e7cc09b72db6adc307d7699a211144b4b6c029cbed9beae1491c10a5fe0678d815a5303843d33c0593fedc9b64068fd0207e280d05aac2c0054fe9ab30857bc3669ee51d34756cfd2e098eb1ab31a03911f6a103f0a16f8f984d9861efdcf4433c
QUIC IETF
    [Packet Length: 38]
    QUIC Short Header DCID=ec523fe99840f9c17c868a88d649147814 PKN=334
        0... .... = Header Form: Short Header (0)
        .1.. .... = Fixed Bit: True
        ..0. .... = Spin Bit: False
        [...0 0... = Reserved: 0]
        [.... .0.. = Key Phase Bit: False]
        [.... ..00 = Packet Number Length: 1 bytes (0)]
        Destination Connection ID: ec523fe99840f9c17c868a88d649147814
        [Packet Number: 334]
        Protected Payload: b9c0e6dc3fc523574f8164c31b6cd156496212
    PING
        Frame Type: PING (0x0000000000000001)
    PADDING Length: 2
        Frame Type: PADDING (0x0000000000000000)
        [Padding Length: 2]

On the peer side these two packet are considered as a unique one
because there may be only one packet by datagram at application encryption
level and reported as a STREAM frame encoding error:

I00000332 0xec523fe99840f9c17c868a88d649147814 con recv packet len=225
mask=b2c69c7827 sample=43a3c83e47db6891bd6a4fd7d7fa3194
I00000332 0xec523fe99840f9c17c868a88d649147814 pkt rx pkn=333 dcid=0xec523fe99840f9c17c868a88d649147814 type=1RTT k=0
I00000332 0xec523fe99840f9c17c868a88d649147814 frm rx 333 1RTT STREAM(0x0e) id=0x0 fin=0 offset=294768 len=144 uni=0
ngtcp2_conn_read_pkt: ERR_FRAME_ENCODING
I00000332 0xec523fe99840f9c17c868a88d649147814 pkt tx pkn=1531039643 dcid=0xae79dfc99d6c65d6 type=1RTT k=0
I00000332 0xec523fe99840f9c17c868a88d649147814 frm tx 1531039643 1RTT CONNECTION_CLOSE(0x1c) error_code=FRAME_ENCODING_ERROR(0x7) frame_type=0 reason_len=0 reason=[]
I00000332 0xec523fe99840f9c17c868a88d649147814 frm tx 1531039643 1RTT PADDING(0x00) len=9

Note here that the sum of the two packet sizes (from capture) is the same as the
packet length reporte by ngtcp2: 187+38 = 225. It also seems that wireshark tries
to parse as much as packet into the same datagram, regardless of the QUIC protocol
rules.

Haproxy traces revealed that this could happen at least when probing the peer.
The recent low level packet building modifications aim was to build
as much as datagrams into the same buffer. But it seems that the
probing packet case treatment has been broken. That said, I have not
identified impacted commit. This issue could be reproduced inside
interop test environment (no possible git bisection).

To fix this, rely on the <probe> variable value to identify if the last
packet built by qc_prep_pkts() was a probing one, then try to
coalesce some others packet into the same datagram if this was not the case.
Of course the test on <probe> value has to be done before setting it
for the next packet.

Must be backported to 3.0.

12 months ago[RELEASE] Released version 3.1-dev2 v3.1-dev2
Willy Tarreau [Sat, 29 Jun 2024 09:28:41 +0000 (11:28 +0200)] 
[RELEASE] Released version 3.1-dev2

Released version 3.1-dev2 with the following main changes :
    - BUG/MINOR: log: fix broken '+bin' logformat node option
    - DEBUG: hlua: distinguish burst timeout errors from exec timeout errors
    - REGTESTS: ssl: fix some regtests 'feature cmd' start condition
    - BUG/MEDIUM: ssl: AWS-LC + TLSv1.3 won't do ECDSA in RSA+ECDSA configuration
    - MINOR: ssl: activate sigalgs feature for AWS-LC
    - REGTESTS: ssl: activate new SSL reg-tests with AWS-LC
    - BUG/MEDIUM: proxy: fix email-alert invalid free
    - REORG: mailers: move free_email_alert() to mailers.c
    - BUG/MINOR: proxy: fix email-alert leak on deinit() (2nd try)
    - DOC: configuration: fix alphabetical order of bind options
    - DOC: management: document ptr lookup for table commands
    - BUG/MAJOR: quic: fix padding with short packets
    - BUG/MAJOR: quic: do not loop on emission on closing/draining state
    - MINOR: sample: date converter takes HTTP date and output an UNIX timestamp
    - SCRIPTS: git-show-backports: do not truncate git-show output
    - DOC: api/event_hdl: small updates, fix an example and add some precisions
    - BUG/MINOR: h3: fix crash on STOP_SENDING receive after GOAWAY emission
    - BUG/MINOR: mux-quic: fix crash on qcs SD alloc failure
    - BUG/MINOR: h3: fix BUG_ON() crash on control stream alloc failure
    - BUG/MINOR: quic: fix BUG_ON() on Tx pkt alloc failure
    - DEV: flags/show-fd-to-flags: adapt to recent versions
    - MINOR: capabilities: export capget and __user_cap_header_struct
    - MINOR: capabilities: prepare support for version 3
    - MINOR: capabilities: use _LINUX_CAPABILITY_VERSION_3
    - MINOR: cli/debug: show dev: add cmdline and version
    - MINOR: cli/debug: show dev: show capabilities
    - MINOR: debug: print gdb hints when crashing
    - BUILD: debug: also declare strlen() in __ABORT_NOW()
    - BUILD: Missing inclusion header for ssize_t type
    - BUG/MINOR: hlua: report proper context upon error in hlua_cli_io_handler_fct()
    - MINOR: cfgparse/log: remove leftover dead code
    - BUG/MEDIUM: stick-table: Decrement the ref count inside lock to kill a session
    - MINOR: stick-table: Always decrement ref count before killing a session
    - REORG: init: do MODE_CHECK_CONDITION logic first
    - REORG: init: encapsulate CHECK_CONDITION logic in a func
    - REORG: init: encapsulate 'reload' sockpair and master CLI listeners creation
    - REORG: init: encapsulate code that reads cfg files
    - BUG/MINOR: server: fix first server template name lookup UAF
    - MINOR: activity: make the memory profiling hash size configurable at build time
    - BUG/MEDIUM: server/dns: prevent DOWN/UP flap upon resolution timeout or error
    - BUG/MEDIUM: h3: ensure the ":method" pseudo header is totally valid
    - BUG/MEDIUM: h3: ensure the ":scheme" pseudo header is totally valid
    - BUG/MEDIUM: quic: fix race-condition in quic_get_cid_tid()
    - BUG/MINOR: quic: fix race condition in qc_check_dcid()
    - BUG/MINOR: quic: fix race-condition on trace for CID retrieval

12 months agoBUG/MINOR: quic: fix race-condition on trace for CID retrieval
Amaury Denoyelle [Thu, 27 Jun 2024 16:52:23 +0000 (18:52 +0200)] 
BUG/MINOR: quic: fix race-condition on trace for CID retrieval

quic_rx_pkt_retrieve_conn() is used when parsing a received datagram
from the listener socket. It returned the quic_conn instance
corresponding to the first packet DCID, unless it is mapped to another
thread.

As expected, global CID tree access is protected by a lock in the
function. However, there is a race condition due to the final trace
where qc instance is dereferenced outside of the lock. Fix this by
adding a new trace under lock protection and remove qc deferencement at
function end.

This may fix first crash of github issue #2607.

This must be backported up to 2.8.

12 months agoBUG/MINOR: quic: fix race condition in qc_check_dcid()
Amaury Denoyelle [Thu, 27 Jun 2024 16:15:08 +0000 (18:15 +0200)] 
BUG/MINOR: quic: fix race condition in qc_check_dcid()

qc_check_dcid() is a function which check that a DCID is associated to
the expected quic_conn instance. This is used for quic_conn socket
receive handler as there is a tiny risk that a datagram to another
connection was received on this socket.

As other operations on global CID tree, a lock must be used to protect
against race condition. However, as previous commit, lock was not held
long enough as CID tree node is accessed outside of the lock region. To
fix this, increase critical section until CID dereferencement is done.

The impact of this bug should be similar to the previous one. However,
risk of crash are even less reduced as it should be extremely rare to
receive datagram for other connections on a quic_conn socket. As such,
most of the time first check condition of qc_check_dcid() is enough.

This may fix first crash of issue github #2607.

This must be backported up to 2.8.

12 months agoBUG/MEDIUM: quic: fix race-condition in quic_get_cid_tid()
Amaury Denoyelle [Thu, 27 Jun 2024 15:15:55 +0000 (17:15 +0200)] 
BUG/MEDIUM: quic: fix race-condition in quic_get_cid_tid()

haproxy generates CID for clients which reuse them as DCID on their
packets. These CID are stored in a global tree quic_cid_trees. Each
operation on this tree must be done under lock protection.

quic_get_cid_tid() is a function which lookups a CID in global tree and
return the associated thread ID. This is used on datagram reception on
listener socket before redispatching the datagram to the correct thread.
This function uses a lock to protect quic_cid_trees access. However,
lock region is too small as CID tree node is accessed outside of it. Fix
this by extending lock protection for CID dereferencement until thread
ID is retrieved.

The impact of this bug is unknown, but it may possible cause crashes.
However, it is probably rare as most of datagram reception is done on
quic_conn socket which does not uses quic_get_cid_tid().

This may fix first crash of github issue #2607.

This must be backported up to 2.8.

12 months agoBUG/MEDIUM: h3: ensure the ":scheme" pseudo header is totally valid
Amaury Denoyelle [Fri, 28 Jun 2024 08:50:19 +0000 (10:50 +0200)] 
BUG/MEDIUM: h3: ensure the ":scheme" pseudo header is totally valid

Ensure pseudo-header scheme is only constitued of valid characters
according to RFC 9110. If an invalid value is found, the request is
rejected and stream is resetted.

It's the same as for previous commit "BUG/MEDIUM: h3: ensure the
":method" pseudo header is totally valid" except that this time it
applies to the ":scheme" pseudo header.

This must be backported up to 2.6.

12 months agoBUG/MEDIUM: h3: ensure the ":method" pseudo header is totally valid
Amaury Denoyelle [Fri, 28 Jun 2024 08:43:19 +0000 (10:43 +0200)] 
BUG/MEDIUM: h3: ensure the ":method" pseudo header is totally valid

Ensure pseudo-header method is only constitued of valid characters
according to RFC 9110. If an invalid value is found, the request is
rejected and stream is resetted.

Previously only characters forbidden in headers were rejected (NUL/CR/LF),
but this is insufficient for :method, where some other forbidden chars
might be used to trick a non-compliant backend server into seeing a
different path from the one seen by haproxy. Note that header injection
is not possible though.

This must be backported up to 2.6.

Many thanks to Yuki Mogi of FFRI Security Inc for the detailed report
that allowed to quicky spot, confirm and fix the problem.

12 months agoBUG/MEDIUM: server/dns: prevent DOWN/UP flap upon resolution timeout or error
Aurelien DARRAGON [Fri, 28 Jun 2024 07:41:56 +0000 (09:41 +0200)] 
BUG/MEDIUM: server/dns: prevent DOWN/UP flap upon resolution timeout or error

This is a complementary patch to c16eba818 ("BUG/MEDIUM: server/dns:
preserve server's port upon resolution timeout or error").

Indeed, since c16eba818, the port is properly preserved, but unsetting
server's address this way results in server_atomic_sync() function
thinking that we're actually setting a new address and not unsetting
the previous one because addr family is != AF_UNSPEC.

Upon DNS timeout, this could be observed:

[WARNING]  (2588257) : Server http/s1 is going DOWN for maintenance (DNS timeout status). 0 active and 0 backup servers left. 0 sessions active, 0 requeued, 0 remaining in queue.
[WARNING]  (2588257) : Server http/s1 ('test1.localhost') is UP/READY (resolves again).

Notice that server timeouts and then immediately resolves again. Of course
in this case case the server's address was properly set to 0, meaning
that the server will not receive any traffic, but it is confusing and
could result in haproxy temporarily thinking that the server is actually
available while it's not.

To properly fix the issue and restore historical behavior, let's
explicitly set inetaddr's family to AF_UNSPEC after fetching original
server's address.

It should be backported in 3.0 with c16eba818.

12 months agoMINOR: activity: make the memory profiling hash size configurable at build time
Willy Tarreau [Thu, 27 Jun 2024 15:53:18 +0000 (17:53 +0200)] 
MINOR: activity: make the memory profiling hash size configurable at build time

The MEMPROF_HASH_BITS variable was set to 10 without a possibility to
change it (beyond patching the code). After seeing a few reports already
with "other" being listed and a list with close to 1024 entries, it looks
like it's about time to either increase the hash size, or at least make
it configurable for special cases. As a reminder, in order to remain
fast, the algorithm searches no more than 16 places after the hash, so
when a table is almost full, searches are long and new places are rare.

The present patch just makes it possible to redefine it by passing
"-DMEMPROF_HASH_BITS=11" or "-DMEMPROF_HASH_BITS=12" in CFLAGS, and
moves the definition to defaults.h to make it easier to find. Such
values should be way sufficient for the vast majority of use cases.
Maybe in the future we'd change the default. At least this version
should be backported to ease rebuilds, say, till 2.8 or so.

12 months agoBUG/MINOR: server: fix first server template name lookup UAF
Aurelien DARRAGON [Thu, 27 Jun 2024 08:42:44 +0000 (10:42 +0200)] 
BUG/MINOR: server: fix first server template name lookup UAF

This is a follow-up for 7223296 ("BUG/MINOR: server: fix first server
template not being indexed").

Indeed, in 7223296 we added a new call to _srv_parse_set_id_from_prefix()
for the first server before handling additional ones. But we actually
overlooked the fact that _srv_parse_set_id_from_prefix() was already
performed at the end of _srv_parse_tmpl_init() for the same server.

Since _srv_parse_set_id_from_prefix() frees srv->id, it results in UAF
when performing name lookups on the first server, because used_server_name
node key still uses the freed string pointer.

The early _srv_parse_set_id_from_prefix() call (added in 7223296) and
the original one perform the same task, except that the new one is
followed by name node insertion logic required for name lookups to work
properly. So let's simply get rid of the old one at the end of the
function.

_srv_parse_set_id_from_prefix() in the 'err:' label was also removed since
is is now useless as well starting with 7223296 and would trigger the same
bug on error paths. Thanks to Amaury for noticing it.

This bug was discovered while trying to address GH issue #2620.
Thanks to @x-yuri for his detailed report (with working repro).

It should be backported in 3.0 with 7223296.

12 months agoREORG: init: encapsulate code that reads cfg files
Valentine Krasnobaeva [Wed, 26 Jun 2024 15:03:04 +0000 (17:03 +0200)] 
REORG: init: encapsulate code that reads cfg files

Haproxy master process should not read its configuration the second time
after performing reexec and passing to MODE_MWORKER_WAIT. So, to make
this part of init() function more readable and to distinguish better the
point, where configs have been read, let's encapsulate it in a separate
function.

12 months agoREORG: init: encapsulate 'reload' sockpair and master CLI listeners creation
Valentine Krasnobaeva [Wed, 26 Jun 2024 14:21:50 +0000 (16:21 +0200)] 
REORG: init: encapsulate 'reload' sockpair and master CLI listeners creation

Let's encapsulate the logic of 'reload' sockpair and master CLI listeners
creation, used by master CLI into a separate function, as we needed this
only in master-worker runtime  mode. This makes the code of init() more
readable.

12 months agoREORG: init: encapsulate CHECK_CONDITION logic in a func
Valentine Krasnobaeva [Wed, 26 Jun 2024 16:39:45 +0000 (18:39 +0200)] 
REORG: init: encapsulate CHECK_CONDITION logic in a func

As MODE_CHECK_CONDITION logic terminates the process anyway, no matter if
the test for the provided condition was successfull or not, let's
encapsulate it in a separate function. This makes the code of init() more
readable.

12 months agoREORG: init: do MODE_CHECK_CONDITION logic first
Valentine Krasnobaeva [Wed, 26 Jun 2024 16:29:47 +0000 (18:29 +0200)] 
REORG: init: do MODE_CHECK_CONDITION logic first

In MODE_CHECK_CONDITION we only parse check_condition string, provided by
'-cc', and then we evaluate it. Haproxy process terminates at the
end of {if..else} block anyway, if the test has failed or passed. So, it
will be more appropriate to perform MODE_CHECK_CONDITION test first and
then do all other process runtime mode verifications.

12 months agoMINOR: stick-table: Always decrement ref count before killing a session
Christopher Faulet [Wed, 26 Jun 2024 12:45:24 +0000 (14:45 +0200)] 
MINOR: stick-table: Always decrement ref count before killing a session

Guarded functions to kill a sticky session, stksess_kill()
stksess_kill_if_expired(), may or may not decrement and test its reference
counter before really killing it. This depends on a parameter. If it is set
to non-zero value, the ref count is decremented and if it falls to zero, the
session is killed. Otherwise, if this parameter is equal to zero, the
session is killed, regardless the ref count value.

In the code, these functions are always called with a non-zero parameter and
the ref count is always decremented and tested. So, there is no reason to
still have a special case. Especially because it is not really easy to say
if it is supported or not. Does it mean it is possible to kill a sticky
session while it is still referenced somewhere ? probably not. So, does it
mean it is possible to kill a unreferenced session ? This case may be
problematic because the session is accessed outside of any lock and thus may
be released by another thread because it is unreferenced. Enlarging scope of
the lock to avoid any issue is possible but it is a bit of shame to do so
because there is no usage for now.

The best is to simplify the API and remove this case. Now, stksess_kill()
and stksess_kill_if_expired() functions always decrement and test the ref
count before killing a sticky session.

12 months agoBUG/MEDIUM: stick-table: Decrement the ref count inside lock to kill a session
Christopher Faulet [Tue, 25 Jun 2024 06:22:58 +0000 (08:22 +0200)] 
BUG/MEDIUM: stick-table: Decrement the ref count inside lock to kill a session

When we try to kill a session, the shard must be locked before decrementing
the ref count on the session. Otherwise, the ref count can fall to 0 and a
purge task (stktable_trash_oldest or process_table_expire) may release the
session before we have the opportunity to acquire the lock on the shard to
effectively kill the session. This could lead to a double free.

Here is the scenario:

    Thread 1                                 Thread 2

  sktsess_kill(ts)
    if (ATOMIC_DEC(&ts->ref_cnt) != 0)
        return
                   /* here the ref count is 0 */

                                       stktable_trash_oldest()
                                          LOCK(&sh_lock)
                                          if (!ATOMIC_LOAD(&ts->ref_cnf))
                                              __stksess_free(ts)
                                          UNLOCK(&sh_lock)

                  /* here the session was released */
    LOCK(&sh_lock)
    __stksess_free(ts)  <--- double free
    UNLOCK(&sh_lock)

The bug was introduced in 2.9 by the commit 7968fe3889 ("MEDIUM:
stick-table: change the ref_cnt atomically"). The ref count must be
decremented inside the lock for stksess_kill() and sktsess_kill_if_expired()
function.

This patch should fix the issue #2611. It must be backported as far as 2.9. On
the 2.9, there is no sharding. All the table is locked. The patch will have to
be adapted.

12 months agoMINOR: cfgparse/log: remove leftover dead code
Aurelien DARRAGON [Tue, 25 Jun 2024 16:31:29 +0000 (18:31 +0200)] 
MINOR: cfgparse/log: remove leftover dead code

Remove development leftover introduced by commit 15e9c7da6 ("MINOR: log:
add log-profile parsing logic").

Indeed, since "log-profile" section keyword is registered via
REGISTER_CONFIG_SECTION() macro, it is not relevant to declare it in
common_kw_list[] from cfgparse-global.c. All it does is that it could
confuse the user by suggesting him to use "log-profile" inside a global
section when trying to find a best match in cfg_parse_global().

12 months agoBUG/MINOR: hlua: report proper context upon error in hlua_cli_io_handler_fct()
Aurelien DARRAGON [Fri, 21 Jun 2024 17:12:37 +0000 (19:12 +0200)] 
BUG/MINOR: hlua: report proper context upon error in hlua_cli_io_handler_fct()

As a result of copy pasting, hlua_cli_io_handler_fct() used to report lua
exceptions like E_ETMOUT as "Lua converter" instead of "Lua cli".

Let's fix that.

It could be backported to all stable versions.

[ada: for older versions, HLUA_E_BTMOUT case didn't exist so it has to be
 skipped]

12 months agoBUILD: Missing inclusion header for ssize_t type
Frederic Lecaille [Wed, 26 Jun 2024 08:17:09 +0000 (10:17 +0200)] 
BUILD: Missing inclusion header for ssize_t type

Compilation issue detected as follows by gcc:

In file included from src/ncbuf.c:19:
src/ncbuf.c: In function 'ncb_write_off':
include/haproxy/bug.h:144:10: error: unknown type name 'ssize_t'
  144 |   extern ssize_t write(int, const void *, size_t); \

12 months agoBUILD: debug: also declare strlen() in __ABORT_NOW()
Willy Tarreau [Wed, 26 Jun 2024 06:02:09 +0000 (08:02 +0200)] 
BUILD: debug: also declare strlen() in __ABORT_NOW()

Previous commit 8f204fa8ae ("MINOR: debug: print gdb hints when crashing")
broken on the CI where strlen() isn't known. Let's forward-declare it in
the __ABORT_NOW() functions, just like write(). No backport is needed.

12 months agoMINOR: debug: print gdb hints when crashing
Willy Tarreau [Fri, 21 Jun 2024 12:04:46 +0000 (14:04 +0200)] 
MINOR: debug: print gdb hints when crashing

To make bug reporting easier for users, when crashing, let's suggest
what to do. Typically when a BUG_ON() matches, only the current thread
is useful the vast majority of the time, while when the watchdog
triggers, all threads are interesting.

The messages are printed at the end after the dump. We may adjust these
with wiki links in the future is more detailed instructions are relevant.

12 months agoMINOR: cli/debug: show dev: show capabilities
Valentine Krasnobaeva [Fri, 21 Jun 2024 16:11:46 +0000 (18:11 +0200)] 
MINOR: cli/debug: show dev: show capabilities

If haproxy compiled with Linux capabilities support, let's show process
capabilities before applying the configuration and at runtime in 'show dev'
command output. This maybe useful for debugging purposes. Especially in
cases, when process changes its UID and GID to non-priviledged or it
has started and run under non-priviledged UID and needed capabilities are
set by admin on the haproxy binary.

12 months agoMINOR: cli/debug: show dev: add cmdline and version
Valentine Krasnobaeva [Wed, 29 May 2024 09:27:21 +0000 (11:27 +0200)] 
MINOR: cli/debug: show dev: add cmdline and version

'show dev' command is very convenient to obtain haproxy debugging information,
while process is run in container. Let's extend its output with version and
cmdline. cmdline is useful in a way, as it shows absolute binary path and its
arguments, because sometimes the person, who is debugging failing container is
not the same, who has created and deployed it.

argc and argv are stored in the exported global structure, because
feed_post_mortem() is added as a post check function callback in the
post_check_list. So we can't simply change the signature of
feed_post_mortem(), without breaking other post check callbacks APIs.

Parsers are not supposed to modify argv, so we can safely bypass its pointer
to debug_parse_cli_show_dev(), without copying all argument stings somewhere
in the heap or on stack.

12 months agoMINOR: capabilities: use _LINUX_CAPABILITY_VERSION_3
Valentine Krasnobaeva [Fri, 21 Jun 2024 23:03:38 +0000 (01:03 +0200)] 
MINOR: capabilities: use _LINUX_CAPABILITY_VERSION_3

Linux kernel shows the warning below, when _LINUX_CAPABILITY_VERSION_1 is
used in capset() and capget().

        [1710243.523230] capability: warning: `haproxy' uses 32-bit capabilities (legacy support in use)

This triggers questions from users. Warning is shown by kernel, because
since Linux 2.6.25, 64-bit capabilities support was introduced in
_LINUX_CAPABILITY_VERSION_2. It's in order to be able to continiously
extend capabilities list with the new ones.

We can't use _LINUX_CAPABILITY_VERSION_2, because this version triggers
another warning, according linux/kernel/capability.c (see also more details
about it in comments from kernel sources and in man capset(2)).

kernel/capability.c:
    ...
    static int cap_validate_magic(cap_user_header_t header, unsigned *tocopy)
    {
            __u32 version;

            if (get_user(version, &header->version))
                    return -EFAULT;

            switch (version) {
            case _LINUX_CAPABILITY_VERSION_1:
                    warn_legacy_capability_use();
                    *tocopy = _LINUX_CAPABILITY_U32S_1;
                    break;
            case _LINUX_CAPABILITY_VERSION_2:
                    warn_deprecated_v2();
                    fallthrough;    /* v3 is otherwise equivalent to v2 */
            case _LINUX_CAPABILITY_VERSION_3:
                    *tocopy = _LINUX_CAPABILITY_U32S_3;
                    break;
            default:
            ...

So, to avoid any warnings, lets use _LINUX_CAPABILITY_VERSION_3, which
according to comments in linux/kernel/capability.c, has the same
functionality as _LINUX_CAPABILITY_VERSION_2 (i.e. array of 2
__user_cap_data_struct with 32-bits integers for each capability set), but
comes in Linux 2.6.26 with a header change, in order to protect legacy
source code.

For the moment, we don't authorize capabilities higher, than CAP_SYS_ADMIN
(21-st bit), so we always check the "low" 32 bits, i.e.
__user_cap_data_struct[0].

12 months agoMINOR: capabilities: prepare support for version 3
Valentine Krasnobaeva [Fri, 21 Jun 2024 22:15:20 +0000 (00:15 +0200)] 
MINOR: capabilities: prepare support for version 3

Commit e338d263a76a ("Add 64-bit capability support to the kernel")
introduces in the kernel _LINUX_CAPABILITY_VERSION_1 and
_LINUX_CAPABILITY_VERSION_2 and its corresponded magic numbers "1"
(_LINUX_CAPABILITY_U32S_1) and "2" (_LINUX_CAPABILITY_VERSION_2).

Capabilities sets, since this commit, are composed as an arrays of
 __user_cap_data_struct with length defined in version's magic number
(e.g. struct __user_cap_data_struct kdata[_LINUX_CAPABILITY_U32S_1]).

These magic numbers also help the kernel to figure out how many data
(in __user_cap_data_struct "units") it needs to copy_from/to_user in
capset/capget syscalls.

In order to use _LINUX_CAPABILITY_VERSION_3 in the next commit (it has the
same functionality as version 2), let's follow the kernel code and let's
allocate memory to store 32-capabilities as an array of
__user_cap_data_struct with the length of 1 (_LINUX_CAPABILITY_U32S_1).

12 months agoMINOR: capabilities: export capget and __user_cap_header_struct
Valentine Krasnobaeva [Fri, 31 May 2024 16:01:07 +0000 (18:01 +0200)] 
MINOR: capabilities: export capget and __user_cap_header_struct

To be able to show process capabilities before applying its configuration and
also at runtime in 'show dev' command output, we need to export the wrapper
around capget() syscall. It also seems more handy to place
__user_cap_header_struct in .data section and declare it as globally
accessible, as we always fill it with the same values. This avoids allocate
and fill these 8 bytes each time on the stack frame, when capget() or capset()
wrappers are called.

12 months agoDEV: flags/show-fd-to-flags: adapt to recent versions
Willy Tarreau [Mon, 24 Jun 2024 09:05:08 +0000 (11:05 +0200)] 
DEV: flags/show-fd-to-flags: adapt to recent versions

The script hadn't been updated since it was introduced, and the
hard-coded field 12 doesn't match anymore (it's 16 now). Let's just
use "grep -o cflg..." to extract the desired part more flexibly.
This can be backported at least to 3.0, probably further, but it
will need to be tested prior to this. Better not bring it too far,
it's only used when debugging.

12 months agoBUG/MINOR: quic: fix BUG_ON() on Tx pkt alloc failure
Amaury Denoyelle [Thu, 20 Jun 2024 15:54:04 +0000 (17:54 +0200)] 
BUG/MINOR: quic: fix BUG_ON() on Tx pkt alloc failure

On quic_tx_packet allocation failure, it is possible to trigger BUG_ON()
crash on INITIAL packet building. This statement is responsible to
ensure INITIAL packets are padded to 1.200 bytes as required. If a
packet on higher encryption level allocation fails, PADDING frame cannot
properly encoded, despite the INITIAL packet properly built.

This crash happens due to qc_txb_store() invokation after quic_tx_packet
allocation failure to validate already built packets. However, this
statement is unneeded as qc_purge_tx_buf() is called just after. Simply
remove qc_txb_store() to fix this issue.

This was detected using -dMfail.

This should be backported up to 2.6.

12 months agoBUG/MINOR: h3: fix BUG_ON() crash on control stream alloc failure
Amaury Denoyelle [Thu, 20 Jun 2024 15:51:35 +0000 (17:51 +0200)] 
BUG/MINOR: h3: fix BUG_ON() crash on control stream alloc failure

BUG_ON() from qcc_set_error() is triggered on HTTP/3 control stream
allocation failure. This is caused because both h3_finalize() and
qcc_init_stream_local() call qcc_set_error() which is forbidden to
prevent error code erasure.

Fix this by removing qcc_set_error() invocation from h3_finalize() on
allocation failure. Note that this function is still responsible to use
it on SETTING frame emission failure.

This was detected using -dMfail.

This must be backported up to 3.0.

12 months agoBUG/MINOR: mux-quic: fix crash on qcs SD alloc failure
Amaury Denoyelle [Thu, 20 Jun 2024 12:41:22 +0000 (14:41 +0200)] 
BUG/MINOR: mux-quic: fix crash on qcs SD alloc failure

Since the following commit, sedesc are created since QCS instantiation
in qcs_new().
  086e51017e7731ee9820b882fe6e8cc5f0dd5352
  BUG/MEDIUM: mux-quic: Create sedesc in same time of the QUIC stream

However, sedesc is initialized before other QCS mandatory fields. If
sedesc allocation fails, a crash would occur on qcs_free() invocation
for QCS early release. To fix this, delay sedesc allocation until
function end.

This bug was detected using -dMfail.

This should be backported up to 2.6.

12 months agoBUG/MINOR: h3: fix crash on STOP_SENDING receive after GOAWAY emission
Amaury Denoyelle [Fri, 21 Jun 2024 12:45:04 +0000 (14:45 +0200)] 
BUG/MINOR: h3: fix crash on STOP_SENDING receive after GOAWAY emission

After emitting a HTTP/3 GOAWAY frame, opening of streams higher than
advertised ID was prevented. h3_attach operation would return success
but without allocating H3S stream context for QCS. In addition, the
stream would be immediately scheduled for RESET_STREAM emission.

Despite the immediate stream close, the current is not sufficient enough
and can cause crashes. When of this occurence can be found if
STOP_SENDING is the first frame received for a stream. A crash would
occur under qcc_recv_stop_sending() after h3_attach invokation, when
h3_close() is used which try to access to H3S context.

To fix this, change h3_attach API. In case of success, H3S stream
context is always allocated, even if the stream will be scheduled for
immediate close. This renders the code more reliable.

This crash should be extremely rare, as it can only happen after GOAWAY
emission, which is only used on soft-stop or reload.

This should solve the second crash occurence reported on GH #2607.

This must be backported up to 2.8.

12 months agoDOC: api/event_hdl: small updates, fix an example and add some precisions
Aurelien DARRAGON [Fri, 21 Jun 2024 15:56:51 +0000 (17:56 +0200)] 
DOC: api/event_hdl: small updates, fix an example and add some precisions

Fix an example suggesting that using EVENT_HDL_SUB_TYPE(x, y) with y being
0 was valid. Then add some notes to explain how to use
EVENT_HDL_SUB_FAMILY() and EVENT_HDL_SUB_TYPE() with valid values.

Also mention that the feature is available starting from 2.8 and not 2.7.
Finally, perform some purely cosmetic updates.

This could be backported in 2.8.

12 months agoSCRIPTS: git-show-backports: do not truncate git-show output
Amaury Denoyelle [Thu, 20 Jun 2024 09:22:59 +0000 (11:22 +0200)] 
SCRIPTS: git-show-backports: do not truncate git-show output

git-show-backports lists a git-show command which can be used to inspect
all commits subject to backport. This command specifies formatting
option to reproduce default git-show output, especially for commit
messages indented with 4 spaces character. However, it also add wrapping
on message line longer than 72 characters. This reduce lisibility of
messages where large info are written such as backtraces.

Improve this by changing git-show format option. Use a limit value of 0
to disable wrapping while preserving indentation.

This could be backported to every stable version to simplify backporting
process.

12 months agoMINOR: sample: date converter takes HTTP date and output an UNIX timestamp
William Lallemand [Fri, 14 Jun 2024 07:38:14 +0000 (09:38 +0200)] 
MINOR: sample: date converter takes HTTP date and output an UNIX timestamp

The `date` converter takes an HTTP date in input, it could be either a
imf, rfc850 or asctime date. It will output an UNIX timestamp.

12 months agoBUG/MAJOR: quic: do not loop on emission on closing/draining state
Amaury Denoyelle [Mon, 17 Jun 2024 13:39:24 +0000 (15:39 +0200)] 
BUG/MAJOR: quic: do not loop on emission on closing/draining state

To emit CONNECTION_CLOSE frame, a special buffer is allocated via
qc_txb_store(). This is due to QUIC_FL_CONN_IMMEDIATE_CLOSE flag.
However this flag is reset after qc_send_ppkts() invocation to prevent
reemission of CONNECTION_CLOSE frame.

qc_send() can invoke multiple times a series of qc_prep_pkts() +
qc_send_ppkts() to emit several datagrams. However, this may cause a
crash if on first loop a CONNECTION_CLOSE is emitted. On the next loop
iteration, QUIC_FL_CONN_IMMEDIATE_CLOSE is resetted, thus qc_prep_pkts()
will use the wrong buffer size as end delimiter. In some cases, this may
cause a BUG_ON() crash due to b_add() outside of buffer.

This bug can be reproduced by using a while loop of ngtcp2-client and
interrupting them randomly via Ctrl+C.

Here is the patch which introduce this regression :
  cdfceb10ae136b02e51f9bb346321cf0045d58e0
  MINOR: quic: refactor qc_prep_pkts() loop

12 months agoBUG/MAJOR: quic: fix padding with short packets
Amaury Denoyelle [Tue, 18 Jun 2024 13:20:32 +0000 (15:20 +0200)] 
BUG/MAJOR: quic: fix padding with short packets

QUIC sending functions were extended to be more flexible. Of all the
changes, they support now iterating over a variable instance of QEL
instance of only 2 previously. This change has rendered PADDING emission
less previsible, which was adjusted via the following patch :

  a60609f1aa3e5f61d2a2286fdb40ebf6936a80ee
  BUG/MINOR: quic: fix padding of INITIAL packets

Its main purpose was to ensure PADDING would only be generated for the
last iterated QEL instance, to avoid unnecessary padding. In parallel, a
BUG_ON() statement ensure that built INITIAL packets are always padded
to 1.200 bytes as necessary before emitted them.

This BUG_ON() statement caused crash in one particular occurence : when
building datagrams that mixed Initial long packets and 1-RTT short
packets. This last occurence type does not have a length field in its
header, contrary to Long packets. This caused a miscalculation for the
necessary padding size, with INITIAL packets not padded enough to reach
the necessary 1.200 bytes size.

This issue was detected on 3.0.2. It can be reproduced by using 0-RTT
combined with latency. Here are the used commands :

  $ ngtcp2-client --tp-file=/tmp/ngtcp2-tp.txt \
    --session-file=/tmp/ngtcp2-session.txt --exit-on-all-streams-close \
    127.0.0.1 20443 "https://[::]/?s=32o"
  $ sudo tc qdisc add dev lo root netem latency 500ms

Note that this issue cannot be reproduced on current dev version.
Indeed, it seems that the following patch introduce a slight change in
packet building ordering :

  cdfceb10ae136b02e51f9bb346321cf0045d58e0
  MINOR: quic: refactor qc_prep_pkts() loop

This must be backported to 3.0.

This should fix github issue #2609.

12 months agoDOC: management: document ptr lookup for table commands
Aurelien DARRAGON [Tue, 18 Jun 2024 20:19:30 +0000 (22:19 +0200)] 
DOC: management: document ptr lookup for table commands

Add missing documentation and examples for the optional ptr lookup method
for table {show,set,clear} commands introduced in commit 9b2717e7 ("MINOR:
stktable: use {show,set,clear} table with ptr"), as initially described in
GH #2118.

It may be backported in 3.0.

12 months agoDOC: configuration: fix alphabetical order of bind options
William Lallemand [Tue, 18 Jun 2024 10:08:19 +0000 (12:08 +0200)] 
DOC: configuration: fix alphabetical order of bind options

Put the curves, ecdhe, severity-output, v4v6 and v6only keyword at the
right place.

Fix issue #2594.

Could be backported in every stable versions.

12 months agoBUG/MINOR: proxy: fix email-alert leak on deinit() (2nd try)
Aurelien DARRAGON [Mon, 17 Jun 2024 16:53:48 +0000 (18:53 +0200)] 
BUG/MINOR: proxy: fix email-alert leak on deinit() (2nd try)

As shown in GH #2608 and ("BUG/MEDIUM: proxy: fix email-alert invalid
free"), simply calling free_email_alert() from free_proxy() is not the
right thing to do.

In this patch, we reuse proxy->email_alert.set memory space to introduce
proxy->email_alert.flags in order to support 2 flags:
PR_EMAIL_ALERT_SET (to mimic proxy->email_alert.set) and
PR_EMAIL_ALERT_RESOLVED (set once init_email_alert() was called on the
proxy to resolve email_alert.mailer pointer).

Thanks to PR_EMAIL_ALERT_RESOLVED flag, free_email_alert() may now
properly handle the freeing of proxy email_alert settings: if the RESOLVED
flag is set, then it means the .email_alert.mailers.name parsing hint was
replaced by the actual mailers pointer, thus no free should be attempted.

No backport needed: as described in ("BUG/MEDIUM: proxy: fix email-alert
invalid free"), this historical leak is not sensitive as it cannot be
triggered during runtime.. thus given that the fix is not backport-
friendly, it's not worth the trouble.

12 months agoREORG: mailers: move free_email_alert() to mailers.c
Aurelien DARRAGON [Mon, 17 Jun 2024 16:39:19 +0000 (18:39 +0200)] 
REORG: mailers: move free_email_alert() to mailers.c

free_email_alert() was declared in cfgparse.c, but it should belong to
mailers.c instead.

12 months agoBUG/MEDIUM: proxy: fix email-alert invalid free
Aurelien DARRAGON [Mon, 17 Jun 2024 16:07:22 +0000 (18:07 +0200)] 
BUG/MEDIUM: proxy: fix email-alert invalid free

In fa90a7d3 ("BUG/MINOR: proxy: fix email-alert leak on deinit()"), I
tried to fix email-alert deinit() leak the simple way by leveraging
existing free_email_alert() helper function which was already used for
freeing email alert settings used in a default section.

However, as described in GH #2608, there is a subtelty that makes
free_email_alert() not suitable for use from free_proxy().

Indeed, proxy 'mailers.name' hint shares the same memory space than the
pointer to the corresponding mailers section (once the proxy is resolved,
name hint is replaced by the pointer to the section). However, since both
values share the same space (through union), we have to take care of not
freeing `mailers.name` once init_email_alert() was called on the proxy.

Unfortunately, free_email_alert() isn't protected against that, causing
double free() during deinit when mailers section is referenced from
multiple proxy sections. Since there is no easy fix, and that the leak in
itself isn't a big deal (fa90a7d3 was simply an opportunistic fix rather
than a must-have given that the leak only occurs during deinit and not
during runtime), let's actually revert the fix to restore legacy behavior
and prevent deinit errors.

Thanks to @snetat for having reported the issue on Github as well as
providing relevant infos to pinpoint the bug.

It should be backported everywhere fa90a7d3 was backported.
[ada: for versions prior to 3.0, simply revert the offending commit using
'git revert' as proxy_free_common() first appears in 3.0]

12 months agoREGTESTS: ssl: activate new SSL reg-tests with AWS-LC
William Lallemand [Mon, 17 Jun 2024 13:31:24 +0000 (15:31 +0200)] 
REGTESTS: ssl: activate new SSL reg-tests with AWS-LC

Prerequisites are now available in AWS-LC, so we can enable these
reg-tests.

With this patch, aws-lc only has 5 reg-tests that are not working:
- reg-tests/ssl/ssl_reuse.vtc: stateful session resumption is only supported with TLSv1.2
- reg-tests/ssl/ssl_curve_name.vtc: function to extract curve name is not available
- reg-tests/ssl/ssl_errors.vtc: errors are not the same than OpenSSL
- reg-tests/ssl/ssl_dh.vtc: AWS-LC does not support DH
- reg-tests/ssl/ssl_curves.vtc: not working correctly

Which means most of the features are working correctly.

12 months agoMINOR: ssl: activate sigalgs feature for AWS-LC
William Lallemand [Mon, 17 Jun 2024 13:22:28 +0000 (15:22 +0200)] 
MINOR: ssl: activate sigalgs feature for AWS-LC

AWSLC lacks the SSL_CTX_set1_sigalgs_list define, however the function
exists, which disables the feature in HAProxy, even if we could have
build with it.

SSL_CTX_set1_client_sigalgs_list() is not available, though.

This patch introduce the define so the feature is enabled.

12 months agoBUG/MEDIUM: ssl: AWS-LC + TLSv1.3 won't do ECDSA in RSA+ECDSA configuration
William Lallemand [Fri, 14 Jun 2024 22:25:16 +0000 (00:25 +0200)] 
BUG/MEDIUM: ssl: AWS-LC + TLSv1.3 won't do ECDSA in RSA+ECDSA configuration

SSL_get_ciphers() in AWS-LC seems to lack the TLSv1.3 ciphersuites,
which break the ECDSA key selection when doing TLSv1.3.

An issue was opened https://github.com/aws/aws-lc/issues/1638

Indeed, in ssl_sock_switchctx_cbk(), the sigalgs is used to determine if
ECDSA is doable or not, then the function compares the list of ciphers in
the clienthello with the list of configured ciphers.

The fix solves the issue by never skipping the TLSv1.3 ciphersuites,
even if they are not in SSL_get_ciphers().

12 months agoREGTESTS: ssl: fix some regtests 'feature cmd' start condition
William Lallemand [Fri, 14 Jun 2024 14:56:58 +0000 (16:56 +0200)] 
REGTESTS: ssl: fix some regtests 'feature cmd' start condition

Since patch fde517b ("REGTESTS: wolfssl: temporarly disable some failing
reg-tests") some 'feature cmd' lines have an extra quotation mark, so
they were disable in every cases.

Must be backported to 2.9.

12 months agoDEBUG: hlua: distinguish burst timeout errors from exec timeout errors
Aurelien DARRAGON [Thu, 13 Jun 2024 17:31:29 +0000 (19:31 +0200)] 
DEBUG: hlua: distinguish burst timeout errors from exec timeout errors

hlua burst timeout was introduced in 58e36e5b1 ("MEDIUM: hlua: introduce
tune.lua.burst-timeout").

It is a safety measure that allows to detect when too much time is spent
on a single lua execution (between 2 interruptions/yields), meaning that
the current thread is not able to perform other tasks. Such scenario
should be avoided because it will cause thread contention which may have
negative performance impact and could cause the watchdog to trigger. When
the burst timeout is exceeded, the current Lua execution is aborted and a
timeout error is reported to the user.

Unfortunately, the same error is currently being reported for cumulative
(AKA execution) timeout and for burst timeout, which may be confusing to
the user.

Indeed, "execution timeout" error historically results from the current
hlua context exceeding the total (cumulative) time it's allowed to run.
It is set per lua context using the dedicated tunables:
 - tune.lua.session-timeout
 - tune.lua.task-timeout
 - tune.lua.service-timeout

We've already faced an user report where the user was able to trigger the
burst timeout and got "Lua task: execution timeout." error while the user
didn't set cumulative timeout. Thus the error was actually confusing
because it was indeed the burst timeout which was causing it due to the
use of cpu-intensive call from within the task without sufficient manual
"yield" keypoints around the cpu-intensive call to ensure it runs on a
dedicated scheduler cycle.

In this patch we make it so burst timeout related errors are reported as
"burst timeout" errors instead of "execution timeout" errors (which
in fact became the generic timeout errors catchall with 58e36e5b1).

To do this, hlua_timer_check() now returns a different value depending if
the exeeded timeout is the burst one or the cumulative one, which allows
us to return either HLUA_E_ETMOUT or HLUA_E_BTMOUT in hlua_ctx_resume().

It should improve the situation described in GH #2356 and may possibly be
backported with 58e36e5b1 to improve error reporting if it applies without
resistance.

12 months agoBUG/MINOR: log: fix broken '+bin' logformat node option
Aurelien DARRAGON [Fri, 14 Jun 2024 16:01:45 +0000 (18:01 +0200)] 
BUG/MINOR: log: fix broken '+bin' logformat node option

In 12d08cf912 ("BUG/MEDIUM: log: don't ignore disabled node's options"),
while trying to restore historical node option inheritance behavior, I
broke the '+bin' logformat node option recently introduced in b7c3d8c87c
("MINOR: log: add +bin logformat node option").

Indeed, because of 12d08cf912, LOG_OPT_BIN is not set anymore on
individual nodes even if it was set globally, making the feature unusable.
('+bin' is also used for binary cbor encoding)

What I should have done instead is include LOG_OPT_BIN in the options
inherited from global ones. This is what's being done in this commit.
Misleading comment was adjusted.

It must be backported in 3.0 with 12d08cf912.

12 months ago[RELEASE] Released version 3.1-dev1 v3.1-dev1
Christopher Faulet [Fri, 14 Jun 2024 14:04:18 +0000 (16:04 +0200)] 
[RELEASE] Released version 3.1-dev1

Released version 3.1-dev1 with the following main changes :
    - REGTESTS: Remove REQUIRE_VERSION=2.1 from all tests
    - REGTESTS: Remove REQUIRE_VERSION=2.2 from all tests
    - CI: use "--no-install-recommends" for apt-get
    - CI: switch to lua 5.4
    - CI: use USE_PCRE2 instead of USE_PCRE
    - DOC: replace the README by a markdown version
    - CI: VTest: accelerate package install a bit
    - ADMIN: acme.sh: remove the old acme.sh code
    - BUG/MINOR: cfgparse: remove the correct option on httpcheck send-state warning
    - BUG/MINOR: tcpcheck: report correct error in tcp-check rule parser
    - BUG/MINOR: tools: fix possible null-deref in env_expand() on out-of-memory
    - DOC: configuration: add an example for keywords from crt-store
    - CI: speedup apt package install
    - DOC: add the FreeBSD status badge to README.md
    - DOC: change the link to the FreeBSD CI in README.md
    - MINOR: stktable: avoid ambiguous stktable_data_ptr() usage in cli_io_handler_table()
    - BUG/MINOR: hlua: use CertCache.set() from various hlua contexts
    - CLEANUP: hlua: fix CertCache class comment
    - CI: FreeBSD: upgrade image, packages
    - BUG/MEDIUM: h1-htx: Don't state interim responses are bodyless
    - MEDIUM: stconn: Be able to unblock zero-copy data forwarding from done_fastfwd
    - BUG/MEDIUM: mux-quic: Unblock zero-copy forwarding if the txbuf can be released
    - BUG/MINOR: quic: prevent crash on qc_kill_conn()
    - CLEANUP: hlua: use hlua_pusherror() where relevant
    - BUG/MINOR: hlua: don't use lua_pushfstring() when we don't expect LJMP
    - BUG/MINOR: hlua: fix unsafe hlua_pusherror() usage
    - BUG/MINOR: hlua: prevent LJMP in hlua_traceback()
    - CLEANUP: hlua: get rid of hlua_traceback() security checks
    - BUG/MINOR: hlua: fix leak in hlua_ckch_set() error path
    - CLEANUP: hlua: simplify ambiguous lua_insert() usage in hlua_ctx_resume()
    - BUG/MEDIUM: mux-quic: Don't unblock zero-copy fwding if blocked during nego
    - MINOR: mux-quic: Don't send an emtpy H3 DATA frame during zero-copy forwarding
    - BUG/MEDIUM: ssl: wrong priority whem limiting ECDSA ciphers in ECDSA+RSA configuration
    - BUG/MEDIUM: ssl: bad auth selection with TLS1.2 and WolfSSL
    - BUG/MINOR: quic: fix computed length of emitted STREAM frames
    - BUG/MINOR: quic: ensure Tx buf is always purged
    - BUG/MEDIUM: stconn/mux-h1: Fix suspect change causing timeouts
    - BUG/MAJOR: mux-h1:  Properly copy chunked input data during zero-copy nego
    - BUG/MINOR: mux-h1: Use the right variable to set NEGO_FF_FL_EXACT_SIZE flag
    - DOC: install: remove boringssl from the list of supported libraries
    - MINOR: log: fix "http-send-name-header" ignore warning message
    - BUG/MINOR: proxy: fix server_id_hdr_name leak on deinit()
    - BUG/MINOR: proxy: fix log_tag leak on deinit()
    - BUG/MINOR: proxy: fix email-alert leak on deinit()
    - BUG/MINOR: proxy: fix check_{command,path} leak on deinit()
    - BUG/MINOR: proxy: fix dyncookie_key leak on deinit()
    - BUG/MINOR: proxy: fix source interface and usesrc leaks on deinit()
    - BUG/MINOR: proxy: fix header_unique_id leak on deinit()
    - MINOR: proxy: add proxy_free_common() helper function
    - BUG/MEDIUM: proxy: fix UAF with {tcp,http}checks logformat expressions
    - MINOR: log: change wording in lf_expr_postcheck() error message
    - BUG/MEDIUM: log: fix lf_expr_postcheck() behavior with default section
    - CLEANUP: log/proxy: fix comment in proxy_free_common()
    - DOC: config: move "hash-key" from proxy to server options
    - DOC: config: add missing section hint for "guid" proxy keyword
    - DOC: config: add missing context hint for new server and proxy keywords
    - BUG/MINOR: promex: Skip resolvers metrics when there is no resolver section
    - DOC: internals: add a documentation about the master worker
    - BUG/MAJOR: mux-h1: Prevent any UAF on H1 connection after draining a request
    - BUG/MINOR: quic: fix padding of INITIAL packets
    - OPTIM: quic: fill whole Tx buffer if needed
    - MINOR: quic: refactor qc_build_pkt() error handling
    - MINOR: quic: use global datagram headlen definition
    - MINOR: quic: refactor qc_prep_pkts() loop
    - DOC/MINOR: management: add missed -dR and -dv options
    - DOC/MINOR: management: add -dZ option
    - DOC: management: rename show stats domain cli "dns" to "resolvers"
    - REORG: log: reorder send log helpers by dependency order
    - MINOR: session: expose session_embryonic_build_legacy_err() function
    - MEDIUM: log/session: handle embryonic session log within sess_log()
    - MINOR: log: provide sending log context to process_send_log() when available
    - MINOR: log: add log_orig_to_str() function
    - MINOR: log: provide log origin in logformat expressions using '%OG'
    - CLEANUP: log: remove ambiguous legacy comment for resolve_logger()
    - MINOR: log/backend: always free parsing hints in resolve_logger()
    - MINOR: log: make resolve_logger() static
    - MINOR: log: provide proxy context to resolve_logger()
    - MINOR: log: add __send_log_set_metadata_sd helper
    - MINOR: log: add logger flags
    - MINOR: log: add log-profile parsing logic
    - MINOR: log: add log profile buildlines
    - MEDIUM: log: handle log-profile in process_send_log()
    - DOC: config: add documentation for log profiles
    - REGTESTS: log: add a test for log-profile
    - MINOR: ssl: add ssl_sock_bind_verifycbk() in ssl_sock.h
    - REORG: ssl: move the SNI selection code in ssl_clienthello.c
    - BUILD: ssl: fix build with wolfSSL
    - CI: github: upgrade aws-lc to 1.29.0
    - Revert "CI: github: upgrade aws-lc to 1.29.0"
    - MEDIUM: ssl: support for ECDA+RSA certificate selection with AWS-LC
    - BUILD: ssl: disable deprecated functions for AWS-LC 1.29.0
    - MINOR: ssl: relax the 'ssl.default-dh-param' keyword parsing
    - CI: github: upgrade aws-lc to 1.29.0
    - DOC: INSTALL: minimum AWS-LC version is v1.22.0
    - CI: github: do the AWS-LC weekly build with ERR=1

12 months agoCI: github: do the AWS-LC weekly build with ERR=1
William Lallemand [Fri, 14 Jun 2024 10:18:32 +0000 (12:18 +0200)] 
CI: github: do the AWS-LC weekly build with ERR=1

The weekly CI that tries new version of AWS-LC was not building with
ERR=1, which let us think that everything was good but there was in fact
new warning that we missed.

Add ERR=1 to the build so the CI will failed for any new warning.

12 months agoDOC: INSTALL: minimum AWS-LC version is v1.22.0
William Lallemand [Fri, 14 Jun 2024 10:06:03 +0000 (12:06 +0200)] 
DOC: INSTALL: minimum AWS-LC version is v1.22.0

Change the minimum AWS-LC version required

12 months agoCI: github: upgrade aws-lc to 1.29.0
William Lallemand [Thu, 13 Jun 2024 15:11:04 +0000 (17:11 +0200)] 
CI: github: upgrade aws-lc to 1.29.0

Upgrade aws-lc to 1.29.0 on the push CI.

12 months agoMINOR: ssl: relax the 'ssl.default-dh-param' keyword parsing
William Lallemand [Fri, 14 Jun 2024 09:23:44 +0000 (11:23 +0200)] 
MINOR: ssl: relax the 'ssl.default-dh-param' keyword parsing

Some libraries are ignoring SSL_CTX_set_tmp_dh_callback(), but disabling
the 'ssl.default-dh-param' keyword when the function is not supported would
result in an error instead of silently continuing. This patch emits a
warning when the keyword is not supported instead of a loading failure.

12 months agoBUILD: ssl: disable deprecated functions for AWS-LC 1.29.0
William Lallemand [Fri, 14 Jun 2024 08:01:46 +0000 (10:01 +0200)] 
BUILD: ssl: disable deprecated functions for AWS-LC 1.29.0

AWS-LC have a lot of functions that does nothing, which are now
deprecated and emits some warning.

This patch disables the following useless functions that emits a warning:
SSL_CTX_get_security_level(), SSL_CTX_set_tmp_dh_callback(),
ERR_load_SSL_strings(), RAND_keep_random_devices_open()

The list of deprecated functions is here:

https://github.com/aws/aws-lc/blob/main/docs/porting/functionality-differences.md

12 months agoMEDIUM: ssl: support for ECDA+RSA certificate selection with AWS-LC
William Lallemand [Thu, 13 Jun 2024 17:11:52 +0000 (19:11 +0200)] 
MEDIUM: ssl: support for ECDA+RSA certificate selection with AWS-LC

AWS-LC does not support the SSL_CTX_set_client_hello_cb() function from
OpenSSL which allows to analyze ciphers and signatures algorithm of the
ClientHello. However it supports the SSL_CTX_set_select_certificate_cb()
which allows the same thing but was the implementation from the
boringSSL side.

This patch uses the SSL_CTX_set_select_certificate_cb() as well as the
SSL_early_callback_ctx_extension_get() function to get the signature
algorithms.

This was successfully tested with openssl s_client as well as
testssl.sh.

This should allow to enable more reg-tests that depend on certificate
selection.

Require at least AWS-LC 1.22.0.

12 months agoRevert "CI: github: upgrade aws-lc to 1.29.0"
William Lallemand [Thu, 13 Jun 2024 15:14:58 +0000 (17:14 +0200)] 
Revert "CI: github: upgrade aws-lc to 1.29.0"

This reverts commit 6e986e7493ad2aa0c5a11c59d1235b03c02ef71c.

12 months agoCI: github: upgrade aws-lc to 1.29.0
William Lallemand [Thu, 13 Jun 2024 15:11:04 +0000 (17:11 +0200)] 
CI: github: upgrade aws-lc to 1.29.0

Upgrade aws-lc to 1.29.0 on the push CI.

12 months agoBUILD: ssl: fix build with wolfSSL
William Lallemand [Thu, 13 Jun 2024 15:01:45 +0000 (17:01 +0200)] 
BUILD: ssl: fix build with wolfSSL

fix build with wolfSSL, broken since the reorg in src/ssl_clienthello.c

12 months agoREORG: ssl: move the SNI selection code in ssl_clienthello.c
William Lallemand [Thu, 13 Jun 2024 14:45:48 +0000 (16:45 +0200)] 
REORG: ssl: move the SNI selection code in ssl_clienthello.c

Move the code which is used to select the final certificate with the
clienthello callback. ssl_sock_client_sni_pool need to be exposed from
outside ssl_sock.c

12 months agoMINOR: ssl: add ssl_sock_bind_verifycbk() in ssl_sock.h
William Lallemand [Thu, 13 Jun 2024 14:44:36 +0000 (16:44 +0200)] 
MINOR: ssl: add ssl_sock_bind_verifycbk() in ssl_sock.h

Add missing ssl_sock_bind_verifycbk() in ssl_sock.h

12 months agoREGTESTS: log: add a test for log-profile
Aurelien DARRAGON [Thu, 6 Jun 2024 09:53:43 +0000 (11:53 +0200)] 
REGTESTS: log: add a test for log-profile

Try to cover some common use-cases for "log-profile" feature. The tests
mainly focus on log-profile section declaration, and testing the behavior
of logformat / log-tag overriding capabilities.

For now, the use of log-profiles is somewhat limited because we lack
the ability to explicitly trigger the log building process at specific
steps during the stream handling. Indeed, for now we rely on
"option logasap" and proxy log-format string content "hacks" to force
the log emission at some specific steps, thus more tests should be added
over the time, when new mechanisms allowing the emission of logs at
expected processing steps will be added, or if new keywords are added to
the log-profile section.

This test requires versions >= 3.0-dev1

12 months agoDOC: config: add documentation for log profiles
Aurelien DARRAGON [Thu, 30 May 2024 15:34:00 +0000 (17:34 +0200)] 
DOC: config: add documentation for log profiles

Now that log-profile parsing logic has been implemented in "MINOR: log:
add log-profile parsing logic" and is actually effective since "MEDIUM:
log: handle log-profile in process_send_log()", let's document the feature
and add some examples.

Log-profile section is declared like this:

  log-profile myprof
    log-tag "custom-tag"

    on error format "%ci: error"
    on any format "(custom httplog) ${HAPROXY_HTTP_LOG_FMT}" sd "[exampleSDID@1234 step=\"accept\" id=\"%ID\"]"

(check out the documentation for the full list of options, some options
are only relevant under specific contexts)

And used this way (from usual "log" directive lines):

  global
    log stdout format rfc5424 profile myprof local0
                              --------------

For now, the use of log-profiles is somewhat limited because we lack
the ability to explicitly trigger the log building process at specific
steps during the stream handling, but it should gain more traction over
the time as the feature evolves and new mechanisms allowing the emission
of logs at expected processing steps will be added.

It should partially fix GH #401

12 months agoMEDIUM: log: handle log-profile in process_send_log()
Aurelien DARRAGON [Thu, 30 May 2024 15:14:58 +0000 (17:14 +0200)] 
MEDIUM: log: handle log-profile in process_send_log()

In previous commit we implemented log-profile parsing logic. Now let's
actually make use of available log-profile information from logger struct
to decide whether we need to rebuild the logline under process_send_log()
according to log profile settings. Nothing is done if the logger didn't
specify a log-profile.

12 months agoMINOR: log: add log profile buildlines
Aurelien DARRAGON [Wed, 31 Jan 2024 17:25:09 +0000 (18:25 +0100)] 
MINOR: log: add log profile buildlines

Now that we have log-profile parsing done, let's prepare for runtime
log-profile handling by adding the necessary string buffer required to
re-build log strings using sess_build_logline() on the fly without
altering regular loglines content.

Indeed, since a different log-profile may (or may not) be specified for
each logger, we must keep the original string and only rebuild a custom
one when required for the current logger (according to the selected log-
profile).

12 months agoMINOR: log: add log-profile parsing logic
Aurelien DARRAGON [Wed, 22 May 2024 15:09:48 +0000 (17:09 +0200)] 
MINOR: log: add log-profile parsing logic

This patch implements prerequisite log-profile struct and parser logic.
It has no effect during runtime for now.

Logformat expressions provided in log-profile "steps" are postchecked
during postparsing for each proxy "log" directive that makes use of a
given profile. (this allows to ensure that the logformat expressions
used in the profile are compatible with proxy using them)

12 months agoMINOR: log: add logger flags
Aurelien DARRAGON [Wed, 29 May 2024 14:50:42 +0000 (16:50 +0200)] 
MINOR: log: add logger flags

Logger struct may benefit from having a "flags" struct member to set
or remove different logger states. For that, we reuse an existing
4 bytes hole in the logger struct to store a 2 bytes flags integer,
leaving the struct with a 2-bytes hole now.

12 months agoMINOR: log: add __send_log_set_metadata_sd helper
Aurelien DARRAGON [Thu, 23 May 2024 13:58:59 +0000 (15:58 +0200)] 
MINOR: log: add __send_log_set_metadata_sd helper

Extract sd metadata assignment in __send_log() to make an inline helper
function out of it in order to be able to use it from other functions if
needed.

12 months agoMINOR: log: provide proxy context to resolve_logger()
Aurelien DARRAGON [Tue, 14 May 2024 15:05:30 +0000 (17:05 +0200)] 
MINOR: log: provide proxy context to resolve_logger()

Prerequisite work for log-profiles, we need to know under which proxy
context the logger is being used. When the info is not available, (ie:
global section or log-forward section, <px> is set to NULL)

12 months agoMINOR: log: make resolve_logger() static
Aurelien DARRAGON [Tue, 14 May 2024 14:53:52 +0000 (16:53 +0200)] 
MINOR: log: make resolve_logger() static

There is no need to expose this internal function, let's make it static.

12 months agoMINOR: log/backend: always free parsing hints in resolve_logger()
Aurelien DARRAGON [Tue, 14 May 2024 14:18:05 +0000 (16:18 +0200)] 
MINOR: log/backend: always free parsing hints in resolve_logger()

Since resolve_logger() always resolves logger target (even when error
occurs), we must take care of freeing parsing hints because free_logger()
won't try to do it if target RESOLVED flag is set on the target.

This isn't considered as a bug because resolve_logger(), being a
postparsing check, will make haproxy immediately exit upon fatal error
in haproxy.c, but it's better to ensure that everything will be properly
freed if we decide to perform a clean exit upon postparsing checks error
in the future.

12 months agoCLEANUP: log: remove ambiguous legacy comment for resolve_logger()
Aurelien DARRAGON [Tue, 14 May 2024 13:11:27 +0000 (15:11 +0200)] 
CLEANUP: log: remove ambiguous legacy comment for resolve_logger()

It is no longer relevant to say that <logger> is used for implicit
settings. In fact the function resolves <logger>, but currently
mainly focuses on loggers's target. However we could extend the
function to perform additional work on the logger itself in the future.

let's adjust the comment to prevent any confusion.

12 months agoMINOR: log: provide log origin in logformat expressions using '%OG'
Aurelien DARRAGON [Mon, 6 May 2024 12:13:11 +0000 (14:13 +0200)] 
MINOR: log: provide log origin in logformat expressions using '%OG'

'%OG' logformat alias may be used to report the log origin (when/where)
that triggered log generation using sess_build_logline().

Possible values are:
  - "sess_error": log was generated during session error handling
  - "sess_killed": log was generated during session abortion (killed
    embryonic session)
  - "txn_accept": log was generated right after frontend conn was accepted
  - "txn_request": log was generated after client request was received
  - "txn_connect": log was generated after backend connection establishment
  - "txn_response": log was generated during server response handling
  - "txn_close": log was generated at the final txn step, before closing
  - "unspec": unknown or not specified

Documentation was updated.

12 months agoMINOR: log: add log_orig_to_str() function
Aurelien DARRAGON [Mon, 6 May 2024 12:33:16 +0000 (14:33 +0200)] 
MINOR: log: add log_orig_to_str() function

Get human readable string from log_orig enum members.

12 months agoMINOR: log: provide sending log context to process_send_log() when available
Aurelien DARRAGON [Thu, 22 Feb 2024 10:29:20 +0000 (11:29 +0100)] 
MINOR: log: provide sending log context to process_send_log() when available

This is another prerequisite work in preparation for log-profiles: in this
patch we make process_send_log() aware of the log origin, primarily aiming
for sess and txn logging steps such as error, accept, connect, close, as
well as relevant sess and stream pointers.

12 months agoMEDIUM: log/session: handle embryonic session log within sess_log()
Aurelien DARRAGON [Wed, 21 Feb 2024 16:26:52 +0000 (17:26 +0100)] 
MEDIUM: log/session: handle embryonic session log within sess_log()

Move the embryonic session logging logic down to sess_log() in preparation
for log-profiles because then log preferences will be set per logger and
not per proxy. Indeed, as each logger may come with its own log-profile
that possibly overrides proxy logformat preferences, the check will need
to be performed at a central place by lower sending functions.

To ensure the change doesn't break existing behavior, a dedicated
sess_log_embryonic() wrapper was added and is exclusively used by
session_kill_embryonic() to indicate that a special logging logic must
be performed under sess_log().

Also, thanks to this change, log-format-sd will now be taken into account
for legacy embryonic session logging.

12 months agoMINOR: session: expose session_embryonic_build_legacy_err() function
Aurelien DARRAGON [Wed, 21 Feb 2024 15:38:46 +0000 (16:38 +0100)] 
MINOR: session: expose session_embryonic_build_legacy_err() function

rename session_build_err_string() to session_embryonic_build_legacy_err()
and add new <out> buffer argument to the prototype. <out> will be used as
destination for the generated string instead of implicitly relying on the
trash buffer. Finally, expose the new function through the header file so
that it becomes usable from any source file.

The function is expected to be called with a session originating from
a connection and should not be used for applets.

12 months agoREORG: log: reorder send log helpers by dependency order
Aurelien DARRAGON [Wed, 22 May 2024 13:19:32 +0000 (15:19 +0200)] 
REORG: log: reorder send log helpers by dependency order

This commit looks messy, but all it does is reorganize send_log() helpers
by dependency order to remove the need of forward-declaring some of them.

Also, since they're all internal helpers, let's explicitly mark them as
static to prevent any misuse.

12 months agoDOC: management: rename show stats domain cli "dns" to "resolvers"
Aurelien DARRAGON [Wed, 12 Jun 2024 09:41:54 +0000 (11:41 +0200)] 
DOC: management: rename show stats domain cli "dns" to "resolvers"

In commit f8642ee82 ("MEDIUM: resolvers: rename dns extra counters to
resolvers extra counters"), we renamed "dns" counters to "resolvers", but
we forgot to update the documentation accordingly.

This may be backported to all stable versions.

12 months agoDOC/MINOR: management: add -dZ option
Valentine Krasnobaeva [Wed, 12 Jun 2024 08:39:11 +0000 (10:39 +0200)] 
DOC/MINOR: management: add -dZ option

Add some description for missed -dZ command line option in
the "3. Starting HAProxy" chapter.

Need to be backported until 2.9.

12 months agoDOC/MINOR: management: add missed -dR and -dv options
Valentine Krasnobaeva [Wed, 12 Jun 2024 08:39:02 +0000 (10:39 +0200)] 
DOC/MINOR: management: add missed -dR and -dv options

Add some description for missed -dR and -dv command line options in
the "3. Starting HAProxy" chapter.

Need to be backported in every stable version.

12 months agoMINOR: quic: refactor qc_prep_pkts() loop
Amaury Denoyelle [Thu, 30 May 2024 12:53:06 +0000 (14:53 +0200)] 
MINOR: quic: refactor qc_prep_pkts() loop

qc_prep_pkts() is built around a double loop iteration. First, it
iterates over every QEL instance register on sending. The inner loop is
used to repeatdly called qc_build_pkt() with a QEL instance. If the QEL
instance has no more data to sent, the next QEL entry is selected. It
can also be interrupted earlier if there is not enough room on the sent
buffer.

Clarify the inner loop by using qc_may_build_pkt() directly into it
besides the check on buffer room left. This function is used to test if
the QEL instance has something to send.

This should simplify send evolution, in particular GSO implementation.

12 months agoMINOR: quic: use global datagram headlen definition
Amaury Denoyelle [Tue, 28 May 2024 16:28:41 +0000 (18:28 +0200)] 
MINOR: quic: use global datagram headlen definition

Each emitted QUIC datagram is prefixed by an out-of-band header. This
header specify the datagram length and the pointer to the first QUIC
packet instance. This header length is defined via QUIC_DGRAM_HEADLEN.

Replace every occurences of manually calculated header length with
globally defined QUIC_DGRAM_HEADLEN. This should ease code maintenance
and simplify GSO implementation.

12 months agoMINOR: quic: refactor qc_build_pkt() error handling
Amaury Denoyelle [Thu, 6 Jun 2024 09:59:34 +0000 (11:59 +0200)] 
MINOR: quic: refactor qc_build_pkt() error handling

qc_build_pkt() error handling was difficult due to multiple error code
possible. Improve this by defining a proper enum to describe the various
error code. Also clean up ending labels inside qc_build_pkt().

12 months agoOPTIM: quic: fill whole Tx buffer if needed
Amaury Denoyelle [Wed, 5 Jun 2024 15:26:14 +0000 (17:26 +0200)] 
OPTIM: quic: fill whole Tx buffer if needed

Previously, packets encoding was stopped as soon as buffer room left is
less than UDP MTU. This is suboptimal if the next packet would be
smaller than that.

To improve this, only check if there is at least enough room for the
mandatory packet header. qc_build_pkt() would ensure there is thus
responsible to return QC_BUILD_PKT_ERR_BUFROOM as soon as buffer left is
insufficient to stop packets encoding. An extra check is added to ensure
end pointer would never exceed buffer end.

This should not have any significant impact on the performance. However,
this renders the code intention clearer.

12 months agoBUG/MINOR: quic: fix padding of INITIAL packets
Amaury Denoyelle [Thu, 30 May 2024 16:06:27 +0000 (18:06 +0200)] 
BUG/MINOR: quic: fix padding of INITIAL packets

API for sending has been extended to support emission on more than 2 QEL
instances. However, this has rendered the PADDING emission for INITIAL
packets less previsible. Indeed, if qc_send() is used with empty QEL
instances, a padding frame may be generated before handling the last QEL
registered, which could cause unnecessary padding to be emitted.

This commit simplify PADDING by only activating it for the last QEL
registered. This ensures that no superfluous padding is generated as if
the minimal INITIAL datagram length is reached, padding is resetted
before handling last QEL instance.

This bug is labelled as minor as haproxy already emit big enough INITIAL
packets coalesced with HANDSHAKE one without needing padding. This
however render the padding code difficult to test. Thus, it may be
useful to force emission on INITIAL qel only without coalescing
HANDSHAKE packet. Here is a sample to reproduce it :

--- a/src/quic_conn.c
+++ b/src/quic_conn.c
@@ -794,6 +794,14 @@ struct task *quic_conn_io_cb(struct task *t, void *context, unsigned int state)
                }
        }

+       if (qc->iel && qel_need_sending(qc->iel, qc)) {
+               struct list empty = LIST_HEAD_INIT(empty);
+               qel_register_send(&send_list, qc->iel, &qc->iel->pktns->tx.frms);
+               if (qc->hel)
+                       qel_register_send(&send_list, qc->hel, &empty);
+               qc_send(qc, 0, &send_list);
+       }
+
        /* Insert each QEL into sending list if needed. */
        list_for_each_entry(qel, &qc->qel_list, list) {
                if (qel_need_sending(qel, qc))

This should be backported up to 3.0.

13 months agoBUG/MAJOR: mux-h1: Prevent any UAF on H1 connection after draining a request
Christopher Faulet [Wed, 12 Jun 2024 12:59:20 +0000 (14:59 +0200)] 
BUG/MAJOR: mux-h1: Prevent any UAF on H1 connection after draining a request

Since 2.9, it is possible to drain the request payload from the H1
multiplexer in case of early reply. When this happens, the upper stream is
detached but the H1 stream is not destroyed. Once the whole request is
drained, the end of the detach stage is finished. So the H1 stream is
destroyed and the H1 connection is ready to be reused, if possible,
otherwise it is released.

And here is the issue. If some data of the next request are received with
last bytes of the drained one, parsing of the next request is immediately
started. The previous H1 stream is destroyed and a new one is created to
handle the parsing.  At this stage the H1 connection may be released, for
instance because of a parsing error. This case was not properly handled.
Instead of immediately exiting the mux, it was still possible to access the
released H1 connection to refresh its timeouts, leading to a UAF issue.

Many thanks to Annika for her invaluable help on this issue.

The patch should fix the issue #2602. It must be backported as far as 2.9.

13 months agoDOC: internals: add a documentation about the master worker
William Lallemand [Wed, 12 Jun 2024 12:46:05 +0000 (14:46 +0200)] 
DOC: internals: add a documentation about the master worker

Add a documentation about the history of the master-worker and how it
was implemented in its first version and how it is currently working.
This is a global view of the architecture, and not an exhaustive
explanation of all mechanisms.

13 months agoBUG/MINOR: promex: Skip resolvers metrics when there is no resolver section
Christopher Faulet [Wed, 12 Jun 2024 06:42:56 +0000 (08:42 +0200)] 
BUG/MINOR: promex: Skip resolvers metrics when there is no resolver section

By default, there is always at least on resolver section, the default one,
based on "/etc/resolv.conf" content. However, it is possible to have no
resolver at all if the file is empty or if any error occurred. Errors are
silently ignored at this stage.

In that case, there was a bug in the Prometheus exporter leading to a crash
because the resolver section list is empty. An invalid resolver entity was
used. To fix the issue we must only take care to not dump resolvers metrics
when there is no resolver.

Thanks to Aurelien to have spotted the offending commit.

This patch should fix the issue #2604. It must be backported to 3.0.

13 months agoDOC: config: add missing context hint for new server and proxy keywords
Aurelien DARRAGON [Tue, 11 Jun 2024 14:39:58 +0000 (16:39 +0200)] 
DOC: config: add missing context hint for new server and proxy keywords

To stay consistent with the work started in 54627f991 ("DOC: config: add
context hint for proxy keywords") and 3d4e1e682 ("DOC: config: add context
hint for server keywords"), we add missing context hint for "guid" (both
proxy and server) keyword and "hash-key" server keyword that were added
during 3.0 development.

This may be backported in 3.0.

13 months agoDOC: config: add missing section hint for "guid" proxy keyword
Aurelien DARRAGON [Tue, 11 Jun 2024 14:52:11 +0000 (16:52 +0200)] 
DOC: config: add missing section hint for "guid" proxy keyword

"guid" proxy keyword added in da754b45 ("MINOR: proxy: implement GUID
support") was lacking the section hint in the keyword description, let's
fix that.

It could be backported in 3.0 with da754b45.

13 months agoDOC: config: move "hash-key" from proxy to server options
Aurelien DARRAGON [Tue, 11 Jun 2024 14:19:04 +0000 (16:19 +0200)] 
DOC: config: move "hash-key" from proxy to server options

As reported by Ashley Morris, "hash-key" keyword which was introduced in
commit faa8c3e0 ("MEDIUM: lb-chash: Deterministic node hashes based on
server address") doesn't belong to proxy keywords and should be found in
5.2 "Server and default-server options" instead.

It should be backported in 3.0 with faa8c3e0

13 months agoCLEANUP: log/proxy: fix comment in proxy_free_common()
Aurelien DARRAGON [Tue, 11 Jun 2024 08:52:37 +0000 (10:52 +0200)] 
CLEANUP: log/proxy: fix comment in proxy_free_common()

Thanks to previous commit, logformat expressions for default proxies are
also postchecked, adjusting a comment that suggests it's not the case.

13 months agoBUG/MEDIUM: log: fix lf_expr_postcheck() behavior with default section
Aurelien DARRAGON [Tue, 11 Jun 2024 08:15:36 +0000 (10:15 +0200)] 
BUG/MEDIUM: log: fix lf_expr_postcheck() behavior with default section

Since 7a21c3a4ef ("MAJOR: log: implement proper postparsing for logformat
expressions"), logformat expressions stored in a default section are not
postchecked anymore. This is because the REGISTER_POST_PROXY_CHECK() only
evaluates regular proxies. Because of this, proxy options which are
automatically enabled on the proxy depending on the logformat expression
features in use are not set on the default proxy, which means such options
are not passed to the regular proxies that inherit from it (proxies that
and will actually be running the logformat expression during runtime).

Because of that, a logformat expression stored inside a default section
and executed by a regular proxy may not behave properly. Also, since
03ca16f38b ("OPTIM: log: resolve logformat options during postparsing"),
it's even worse because logformat node options postresoving is also
skipped, which may also alter logformat expression encoding feature.

To fix the issue, let's add a special case for default proxies in
parse_logformat_string() and lf_expr_postcheck() so that default proxies
are postchecked on the fly during parsing time in a "relaxed" way as we
cannot assume that the features involved in the logformat expression won't
be compatible with the proxy actually running it since we may have
different types of proxies inheriting from the same default section.

This bug was discovered while trying to address GH #2597.

It should be backported to 3.0 with 7a21c3a4ef and 03ca16f38b.

13 months agoMINOR: log: change wording in lf_expr_postcheck() error message
Aurelien DARRAGON [Tue, 11 Jun 2024 07:31:26 +0000 (09:31 +0200)] 
MINOR: log: change wording in lf_expr_postcheck() error message

logformat_node was referenced as "node" in the error message reported
to the user, but in fact it is referred to as "item" in user
documentation. Using "item" in the error message to better comply with
the doc.

Error message was introduced with 7a21c3a4ef ("MAJOR: log: implement
proper postparsing for logformat expressions")