]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: mux-h2: validate HEADERS frame length before reading stream dep
authorWilly Tarreau <w@1wt.eu>
Sat, 23 May 2026 17:42:43 +0000 (19:42 +0200)
committerWilly Tarreau <w@1wt.eu>
Mon, 25 May 2026 08:52:42 +0000 (10:52 +0200)
When the PRIORITY flag is present on a HEADERS frame, the frame must
contain a stream dependency and a weight, for a total of 5 bytes. The
length is checked after reading the stream dep field so theoretically
such a frame could cause up to 4-byte OOB read at the end of the buffer,
though in practice buffers allocated from pools never end on a page
boundary (one extra word at the end) and the anomaly is still detected
after reading the stream ID and the connection aborted with the glitch
count incremented. Thus while not technically correct, practically
speaking it's harmless.

This should be backported to all stable releases.

src/mux_h2.c

index 8a54e3a0c66dac00441a077ce5cec3f246f6bd5d..7546e04a6c34cfaac6a28f35f617a533da58a6f3 100644 (file)
@@ -6236,6 +6236,13 @@ next_frame:
 
        /* Skip StreamDep and weight for now (we don't support PRIORITY) */
        if (h2c->dff & H2_F_HEADERS_PRIORITY) {
+               if (flen < 5) {
+                       h2c_report_glitch(h2c, 1, "too short PRIORITY frame");
+                       TRACE_STATE("too short PRIORITY frame", H2_EV_RX_FRAME|H2_EV_RX_HDR|H2_EV_H2C_ERR|H2_EV_PROTO_ERR, h2c->conn);
+                       h2c_error(h2c, H2_ERR_FRAME_SIZE_ERROR);
+                       goto fail;
+               }
+
                if (read_n32(hdrs) == h2c->dsi) {
                        /* RFC7540#5.3.1 : stream dep may not depend on itself */
                        h2c_report_glitch(h2c, 1, "PRIORITY frame referencing itself");
@@ -6245,13 +6252,6 @@ next_frame:
                        goto fail;
                }
 
-               if (flen < 5) {
-                       h2c_report_glitch(h2c, 1, "too short PRIORITY frame");
-                       TRACE_STATE("too short PRIORITY frame", H2_EV_RX_FRAME|H2_EV_RX_HDR|H2_EV_H2C_ERR|H2_EV_PROTO_ERR, h2c->conn);
-                       h2c_error(h2c, H2_ERR_FRAME_SIZE_ERROR);
-                       goto fail;
-               }
-
                hdrs += 5; // stream dep = 4, weight = 1
                flen -= 5;
        }