]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: quic: Missing STREAM frame type updated
authorFrédéric Lécaille <flecaille@haproxy.com>
Mon, 20 Mar 2023 13:32:59 +0000 (14:32 +0100)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Mon, 27 Mar 2023 14:01:44 +0000 (16:01 +0200)
This patch follows this commit which was not sufficient:
  BUG/MINOR: quic: Missing STREAM frame data pointer updates

Indeed, after updating the ->offset field, the bit which informs the
frame builder of its presence must be systematically set.

This bug was revealed by the following BUG_ON() from
quic_build_stream_frame() :
  bug condition "!!(frm->type & 0x04) != !!stream->offset.key" matched at src/quic_frame.c:515

This should fix the last crash occured on github issue #2074.

Must be backported to 2.6 and 2.7.

include/haproxy/quic_frame.h
src/quic_conn.c

index f75d7e65fcb8c3dfc8fbafc38422f49824a887d7..cf489f759ba431c21b5e9f81f0a319e86fe8e4de 100644 (file)
@@ -255,11 +255,15 @@ static inline void qc_frm_free(struct quic_frame **frm)
 }
 
 /* Move forward <strm> STREAM frame by <data> bytes. */
-static inline void qc_stream_frm_mv_fwd(struct quic_stream *strm, uint64_t data)
+static inline void qc_stream_frm_mv_fwd(struct quic_frame *frm, uint64_t data)
 {
+       struct quic_stream *strm = &frm->stream;
        struct buffer cf_buf;
 
+       /* Set offset bit if not already there. */
        strm->offset.key += data;
+       frm->type |= QUIC_STREAM_FRAME_TYPE_OFF_BIT;
+
        strm->len -= data;
        cf_buf = b_make(b_orig(strm->buf),
                        b_size(strm->buf),
index f4a36f0e4ad8d81b16afc2b87143e603edfcd67d..25ece803909d814d3f90d440dc148c9f7d2f8521 100644 (file)
@@ -1905,7 +1905,7 @@ static inline int qc_requeue_nacked_pkt_tx_frms(struct quic_conn *qc,
                        else if (strm_frm->offset.key < stream_desc->ack_offset) {
                                uint64_t diff = stream_desc->ack_offset - strm_frm->offset.key;
 
-                               qc_stream_frm_mv_fwd(strm_frm, diff);
+                               qc_stream_frm_mv_fwd(frm, diff);
                                TRACE_DEVEL("updated partially acked frame",
                                            QUIC_EV_CONN_PRSAFRM, qc, frm);
                        }
@@ -2562,7 +2562,7 @@ static void qc_dup_pkt_frms(struct quic_conn *qc,
                        else if (strm_frm->offset.key < stream_desc->ack_offset) {
                                uint64_t diff = stream_desc->ack_offset - strm_frm->offset.key;
 
-                               qc_stream_frm_mv_fwd(strm_frm, diff);
+                               qc_stream_frm_mv_fwd(frm, diff);
                                TRACE_DEVEL("updated partially acked frame",
                                            QUIC_EV_CONN_PRSAFRM, qc, frm);
                        }
@@ -7301,7 +7301,7 @@ static inline int qc_build_frms(struct list *outlist, struct list *inlist,
                                else if (strm->offset.key < stream_desc->ack_offset) {
                                        uint64_t diff = stream_desc->ack_offset - strm->offset.key;
 
-                                       qc_stream_frm_mv_fwd(strm, diff);
+                                       qc_stream_frm_mv_fwd(cf, diff);
                                        TRACE_DEVEL("updated partially acked frame",
                                                    QUIC_EV_CONN_PRSAFRM, qc, cf);
                                }