]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: h3: fix use-after-free on mux Rx buffer wrapping
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Wed, 27 Apr 2022 12:41:53 +0000 (14:41 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Thu, 28 Apr 2022 13:18:20 +0000 (15:18 +0200)
Handle wrapping buffer in h3_data_to_htx(). If data is wrapping, first
copy the contiguous data, then copy the data in front of the buffer.

Note that h3_headers_to_htx() is not able to handle wrapping data. For
the moment, a BUG_ON was added as a reminder. This cas never happened,
most probably because HEADERS is the first frame of the stream.

src/h3.c

index 9f1e09b465abb24b3840d94fb75074324930c2da..e516a470c60ab3762f6dcd41c48be6d1d51788b6 100644 (file)
--- a/src/h3.c
+++ b/src/h3.c
@@ -112,6 +112,8 @@ static int h3_headers_to_htx(struct qcs *qcs, struct buffer *buf, uint64_t len,
        struct ist authority = IST_NULL;
        int hdr_idx;
 
+       /* TODO support buffer wrapping */
+       BUG_ON(b_contig_data(buf, 0) != b_data(buf));
        if (qpack_decode_fs((const unsigned char *)b_head(buf), len, tmp, list) < 0)
                return 1;
 
@@ -198,23 +200,31 @@ static int h3_data_to_htx(struct qcs *qcs, struct buffer *buf, uint64_t len,
 {
        struct buffer *appbuf;
        struct htx *htx = NULL;
-       size_t htx_sent;
+       size_t contig = 0, htx_sent = 0;
        int htx_space;
+       char *head;
 
        appbuf = qc_get_buf(qcs, &qcs->rx.app_buf);
        BUG_ON(!appbuf);
        htx = htx_from_buf(appbuf);
 
+ retry:
        htx_space = htx_free_data_space(htx);
        if (!htx_space || htx_space < len) {
                ABORT_NOW(); /* TODO handle this case properly */
        }
 
-       htx_sent = htx_add_data(htx, ist2(b_head(buf), len));
-       if (htx_sent < len) {
-               ABORT_NOW(); /* TODO handle this case properly */
+       contig = b_contig_data(buf, contig);
+       if (len > contig) {
+               htx_sent = htx_add_data(htx, ist2(b_head(buf), contig));
+               head = b_orig(buf);
+               len -= contig;
+               goto retry;
        }
 
+       htx_sent += htx_add_data(htx, ist2(head, len));
+       BUG_ON(htx_sent < len);
+
        if (fin)
                htx->flags |= HTX_FL_EOM;
        htx_to_buf(htx, appbuf);