mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-02-21 13:16:57 +00:00
BUG/MEDIUM: quic: Avoid some crashes upon TX packet allocation failures
If a TX packet cannot be allocated (by qc_build_pkt()), as it can be coalesced to another one, this leads the TX buffer to have remaining not sent prepared data. Then haproxy crashes upon a BUG_ON() triggered by the next call to qc_txb_release(). This may happen only during handshakes. To fix this, qc_build_pkt() returns a new -3 error to dected such allocation failures followed which is for now on followed by a call to qc_purge_txbuf() to send the TX prepared data and purge the TX buffer. Must be backported as far as 2.6.
This commit is contained in:
parent
b21e08cbd2
commit
819690303d
@ -495,6 +495,9 @@ static int qc_prep_app_pkts(struct quic_conn *qc, struct buffer *buf,
|
|||||||
pkt = qc_build_pkt(&pos, end, qel, &qel->tls_ctx, frms, qc, NULL, 0,
|
pkt = qc_build_pkt(&pos, end, qel, &qel->tls_ctx, frms, qc, NULL, 0,
|
||||||
QUIC_PACKET_TYPE_SHORT, must_ack, 0, probe, cc, &err);
|
QUIC_PACKET_TYPE_SHORT, must_ack, 0, probe, cc, &err);
|
||||||
switch (err) {
|
switch (err) {
|
||||||
|
case -3:
|
||||||
|
qc_purge_txbuf(qc, buf);
|
||||||
|
goto leave;
|
||||||
case -2:
|
case -2:
|
||||||
// trace already emitted by function above
|
// trace already emitted by function above
|
||||||
goto leave;
|
goto leave;
|
||||||
@ -1127,6 +1130,9 @@ int qc_prep_hpkts(struct quic_conn *qc, struct buffer *buf, struct list *qels)
|
|||||||
qc, ver, dglen, pkt_type,
|
qc, ver, dglen, pkt_type,
|
||||||
must_ack, padding, probe, cc, &err);
|
must_ack, padding, probe, cc, &err);
|
||||||
switch (err) {
|
switch (err) {
|
||||||
|
case -3:
|
||||||
|
qc_purge_tx_buf(qc, buf);
|
||||||
|
goto leave;
|
||||||
case -2:
|
case -2:
|
||||||
// trace already emitted by function above
|
// trace already emitted by function above
|
||||||
goto leave;
|
goto leave;
|
||||||
@ -2472,8 +2478,8 @@ static inline void quic_tx_packet_init(struct quic_tx_packet *pkt, int type)
|
|||||||
* the end of this buffer, with <pkt_type> as packet type for <qc> QUIC connection
|
* the end of this buffer, with <pkt_type> as packet type for <qc> QUIC connection
|
||||||
* at <qel> encryption level with <frms> list of prebuilt frames.
|
* at <qel> encryption level with <frms> list of prebuilt frames.
|
||||||
*
|
*
|
||||||
* Return -2 if the packet could not be allocated or encrypted for any reason,
|
* Return -3 if the packet could not be allocated, -2 if could not be encrypted for
|
||||||
* -1 if there was not enough room to build a packet.
|
* any reason, -1 if there was not enough room to build a packet.
|
||||||
* XXX NOTE XXX
|
* XXX NOTE XXX
|
||||||
* If you provide provide qc_build_pkt() with a big enough buffer to build a packet as big as
|
* If you provide provide qc_build_pkt() with a big enough buffer to build a packet as big as
|
||||||
* possible (to fill an MTU), the unique reason why this function may fail is the congestion
|
* possible (to fill an MTU), the unique reason why this function may fail is the congestion
|
||||||
@ -2502,7 +2508,7 @@ static struct quic_tx_packet *qc_build_pkt(unsigned char **pos,
|
|||||||
pkt = pool_alloc(pool_head_quic_tx_packet);
|
pkt = pool_alloc(pool_head_quic_tx_packet);
|
||||||
if (!pkt) {
|
if (!pkt) {
|
||||||
TRACE_DEVEL("Not enough memory for a new packet", QUIC_EV_CONN_TXPKT, qc);
|
TRACE_DEVEL("Not enough memory for a new packet", QUIC_EV_CONN_TXPKT, qc);
|
||||||
*err = -2;
|
*err = -3;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user