]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: quic: Too short datagram during packet building failures (aws-lc only)
authorFrederic Lecaille <flecaille@haproxy.com>
Mon, 5 Aug 2024 11:40:51 +0000 (13:40 +0200)
committerFrederic Lecaille <flecaille@haproxy.com>
Mon, 5 Aug 2024 11:40:51 +0000 (13:40 +0200)
This issue was reported by Ilya (@Chipitsine) when building haproxy against
aws-lc in GH #2663 where handshakeloss and handshakecorruption interop tests could
lead haproxy to crash after having built too short datagrams:

FATAL: bug condition "first_pkt->type == QUIC_PACKET_TYPE_INITIAL && (first_pkt->flags & (1UL << 0)) && length < 1200" matched at src/quic_tx.c:163
call trace(13):
| 0x55f4ee4dcc02 [ba d9 00 00 00 48 8d 35]: main-0x195bf2
| 0x55f4ee4e3112 [83 3d 2f 16 35 00 00 0f]: qc_send+0x11f3/0x1b5d
| 0x55f4ee4e9ab4 [85 c0 0f 85 00 f6 ff ff]: quic_conn_io_cb+0xab1/0xf1c
| 0x55f4ee6efa82 [48 c7 c0 f8 55 ff ff 64]: run_tasks_from_lists+0x173/0x9c2
| 0x55f4ee6f05d3 [8b 7d a0 29 c7 85 ff 0f]: process_runnable_tasks+0x302/0x6e6
| 0x55f4ee671bb7 [83 3d 86 72 44 00 01 0f]: run_poll_loop+0x6e/0x57b
| 0x55f4ee672367 [48 8b 1d 22 d4 1d 00 48]: main-0x48d
| 0x55f4ee6755e0 [b8 00 00 00 00 e8 08 61]: main+0x2dec/0x335d

This could happen after Handshake packet building failures which follow a successful
Initial packet into the same datagram. In this case, the datagram could be emitted
with a too short length (<1200 bytes).

To fix this, store the datagram only if the first packet is not an Initial packet
or if its length is big enough (>=1200 bytes).

Must be backported as far as 2.6.

src/quic_tx.c

index 5f81978abda3facf614cc80bb2b881bbd7d17ffc..4126d6423185cf5c6c2ebc105d008e3eadb5b026 100644 (file)
@@ -643,7 +643,11 @@ static int qc_prep_pkts(struct quic_conn *qc, struct buffer *buf,
                                        break;
 
                                case QC_BUILD_PKT_ERR_BUFROOM:
-                                       if (first_pkt)
+                                       /* If a first packet could be built, do not lose it,
+                                        * except if it is an too short Initial.
+                                        */
+                                       if (first_pkt && (first_pkt->type != QUIC_PACKET_TYPE_INITIAL ||
+                                                         wrlen >= QUIC_INITIAL_PACKET_MINLEN))
                                                qc_txb_store(buf, wrlen, first_pkt);
                                        TRACE_PROTO("could not prepare anymore packet", QUIC_EV_CONN_PHPKTS, qc, qel);
                                        break;