]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: xprt_qstrm: read record length in 64bits
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Mon, 20 Apr 2026 06:36:51 +0000 (08:36 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Mon, 20 Apr 2026 07:23:29 +0000 (09:23 +0200)
QMux record lengths are encoded as a QUIC varint. Thus in theory, it
requires a 64bits integer to be able to read the whole value. In
practice, if the record is bigger than bufsize, read operation cannot be
completed and an error must be reported.

This patch fixes record length decoding both in xprt_qstrm layer, which
is now performed in two steps. The value is first read in a 64bits
integer instead of a size_t whose size is dependent on the architecture.
Result is then checked against bufsize and if inferior stored in the
previously used variable (xprt ctx rxrlen member).

This should partially fix build issue reported on github #3334.

No need to backport.

src/xprt_qstrm.c

index 5d4ff94be11b5ba776bf7a15075f4cac03471744..218be34d6013ac2a31bfb811e5fee8db9cc9ff25 100644 (file)
@@ -58,6 +58,7 @@ int conn_recv_qstrm(struct connection *conn, struct xprt_qstrm_ctx *ctx, int fla
        struct quic_frame frm;
        struct buffer *buf = &ctx->rxbuf;
        const unsigned char *pos, *old, *end;
+       uint64_t rlen;
        size_t ret;
 
        if (!conn_ctrl_ready(conn))
@@ -81,12 +82,17 @@ int conn_recv_qstrm(struct connection *conn, struct xprt_qstrm_ctx *ctx, int fla
                goto not_ready;
 
        /* Read record length. */
-       if (!ctx->rxrlen && !b_quic_dec_int(&ctx->rxrlen, buf, NULL))
-               goto not_ready;
+       if (!ctx->rxrlen) {
+               if (!b_quic_dec_int(&rlen, buf, NULL))
+                       goto not_ready;
+
+               /* Reject too small or too big records. */
+               if (!rlen || rlen > b_size(buf))
+                       goto fail;
+
+               ctx->rxrlen = rlen;
+       }
 
-       /* Reject too small or too big records. */
-       if (!ctx->rxrlen || ctx->rxrlen > b_size(buf))
-               goto fail;
        if (ctx->rxrlen > b_data(buf))
                goto not_ready;