]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: mux-h2: Check the number of headers in HEADERS frame after decoding
authorChristopher Faulet <cfaulet@haproxy.com>
Wed, 20 Nov 2024 15:27:34 +0000 (16:27 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Wed, 20 Nov 2024 16:44:22 +0000 (17:44 +0100)
There is no explicit test on the number of headers when a HEADERS frame is
received. It is implicitely limited by the size of the header list. But it
is twice the configured limit to be sure to decode the frame.

So now, a check is performed after the HTX message was created. This way, we
are sure to not exceed the configured limit after the decoding stage. If
there are too many headers, a parsing error is reported.

Note the same is performed on the trailers.

This patch should patially address the issue #2685. It should be backported
to all stable versions.

src/h2.c
src/mux_h2.c

index 731c21c478f8e4d58051a7f0ce4fe74132e4a8fc..536240a6dd797d711a57df6cc7e40134ab55a189 100644 (file)
--- a/src/h2.c
+++ b/src/h2.c
@@ -494,6 +494,10 @@ int h2_make_htx_request(struct http_hdr *list, struct htx *htx, unsigned int *ms
                        goto fail;
        }
 
+       /* Check the number of blocks agains "tune.http.maxhdr" value before adding EOH block */
+       if (htx_nbblks(htx) > global.tune.max_http_hdr)
+               goto fail;
+
        /* now send the end of headers marker */
        if (!htx_add_endof(htx, HTX_BLK_EOH))
                goto fail;
@@ -745,6 +749,10 @@ int h2_make_htx_response(struct http_hdr *list, struct htx *htx, unsigned int *m
                 */
        }
 
+       /* Check the number of blocks agains "tune.http.maxhdr" value before adding EOH block */
+       if (htx_nbblks(htx) > global.tune.max_http_hdr)
+               goto fail;
+
        /* now send the end of headers marker */
        if (!htx_add_endof(htx, HTX_BLK_EOH))
                goto fail;
@@ -812,6 +820,10 @@ int h2_make_htx_trailers(struct http_hdr *list, struct htx *htx)
                        goto fail;
        }
 
+       /* Check the number of blocks agains "tune.http.maxhdr" value before adding EOT block */
+       if (htx_nbblks(htx) > global.tune.max_http_hdr)
+               goto fail;
+
        if (!htx_add_endof(htx, HTX_BLK_EOT))
                goto fail;
 
index c1c7f1a699d9d212a0faf3385faae55d5ff39906..970223c42b30ac280a310cb3c2cf340a085e12da 100644 (file)
@@ -5979,6 +5979,7 @@ next_frame:
        /* Trailers terminate a DATA sequence */
        if (h2_make_htx_trailers(list, htx) <= 0) {
                TRACE_STATE("failed to append HTX trailers into rxbuf", H2_EV_RX_FRAME|H2_EV_RX_HDR|H2_EV_H2S_ERR, h2c->conn);
+               htx->flags |= HTX_FL_PARSING_ERROR;
                goto fail;
        }
        *flags |= H2_SF_ES_RCVD;