]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: quic: ensure offset is properly set for STREAM frames
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Thu, 2 Feb 2023 15:45:07 +0000 (16:45 +0100)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Fri, 3 Feb 2023 08:46:55 +0000 (09:46 +0100)
Care must be taken when reading/writing offset for STREAM frames. A
special OFF bit is set in the frame type to indicate that the field is
present. If not set, it is assumed that offset is 0.

To represent this, offset field of quic_stream structure must always be
initialized with a valid value in regards with its frame type OFF bit.

The previous code has no bug in part because pool_zalloc() is used to
allocate quic_frame instances. To be able to use pool_alloc(), offset is
always explicitely set to 0. If a non-null value is used, OFF bit is set
at the same occasion. A new BUG_ON() statement is added on frame builder
to ensure that the caller has set OFF bit if offset is non null.

This should be backported up to 2.7.

src/mux_quic.c
src/quic_conn.c
src/quic_frame.c

index 98737367e34e315ad0843e11d5f39a4f4d6e576e..fe33e4d51ad436f6d659559a5ad81e015840d501 100644 (file)
@@ -1436,6 +1436,7 @@ static int qcs_build_stream_frm(struct qcs *qcs, struct buffer *out, char fin,
        frm->stream.id = qcs->id;
        frm->stream.buf = out;
        frm->stream.data = (unsigned char *)b_peek(out, head);
+       frm->stream.offset.key = 0;
 
        /* FIN is positioned only when the buffer has been totally emptied. */
        if (fin)
index 26a75f563bebbf90bcc50977a6fb7a73fb3d4bcf..a64cd654d776860efc1223e76adc2340fbfca3d4 100644 (file)
@@ -6857,8 +6857,7 @@ static inline int qc_build_frms(struct list *outlist, struct list *inlist,
                                new_cf->stream.stream = cf->stream.stream;
                                new_cf->stream.buf = cf->stream.buf;
                                new_cf->stream.id = cf->stream.id;
-                               if (cf->type & QUIC_STREAM_FRAME_TYPE_OFF_BIT)
-                                       new_cf->stream.offset = cf->stream.offset;
+                               new_cf->stream.offset = cf->stream.offset;
                                new_cf->stream.len = dlen;
                                new_cf->type |= QUIC_STREAM_FRAME_TYPE_LEN_BIT;
                                /* FIN bit reset */
index 6f299ba2d4e2d9390cba5ea485886de3eb053dd5..0d8bc87f5b892656c25d0626113db36fc4bd6a4e 100644 (file)
@@ -507,6 +507,10 @@ static int quic_build_stream_frame(unsigned char **buf, const unsigned char *end
        struct quic_stream *stream = &frm->stream;
        const unsigned char *wrap;
 
+       /* Caller must set OFF bit if and only if a non-null offset is used. */
+       BUG_ON(!!(frm->type & QUIC_STREAM_FRAME_TYPE_OFF_BIT) !=
+              !!stream->offset.key);
+
        if (!quic_enc_int(buf, end, stream->id) ||
            ((frm->type & QUIC_STREAM_FRAME_TYPE_OFF_BIT) && !quic_enc_int(buf, end, stream->offset.key)) ||
            ((frm->type & QUIC_STREAM_FRAME_TYPE_LEN_BIT) &&