]> git.kaiwu.me - haproxy.git/commitdiff
BUG/MEDIUM: h3: fix BUG_ON() crash with glitch on SETTINGS parsing
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Mon, 19 Oct 2026 11:12:59 +0000 (13:12 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Tue, 20 Oct 2026 08:51:47 +0000 (10:51 +0200)
There is a risk of BUG_ON() crash when glitch are reported via
qcc_report_glitch() before settings a connection-level error using
qcc_set_error(). This happens when reaching the glitch level with the
former function also calling qcc_set_error(). A BUG_ON() is triggered as
it must not be called multiple times per connection to prevent error
code erasure.

This patch fixes glitch reporting during SETTINGS frame parsing. Now,
qcc_report_glitch() is only called after qcc_set_error() on
h3_parse_settings_frm() return.

This must be backported up to 3.0.

src/h3.c

index a5d53f40cd06c39117a5bdfb7d8920a80b6b6c20..5481aaa941b976ecaf60504e1f5e6d0658bf3431 100644 (file)
--- a/src/h3.c
+++ b/src/h3.c
@@ -1769,7 +1769,6 @@ static ssize_t h3_parse_settings_frm(struct h3c *h3c, const struct buffer *buf,
        while (b_data(&b)) {
                if (!b_quic_dec_int(&id, &b, &ret) || !b_quic_dec_int(&value, &b, &ret)) {
                        h3c->err = H3_ERR_FRAME_ERROR;
-                       qcc_report_glitch(h3c->qcc, 1);
                        return -1;
                }
 
@@ -1787,7 +1786,6 @@ static ssize_t h3_parse_settings_frm(struct h3c *h3c, const struct buffer *buf,
                if (id < sizeof(mask)) {
                        if (ha_bit_test(id, &mask)) {
                                h3c->err = H3_ERR_SETTINGS_ERROR;
-                               qcc_report_glitch(h3c->qcc, 1);
                                return -1;
                        }
                        ha_bit_set(id, &mask);
@@ -1818,7 +1816,6 @@ static ssize_t h3_parse_settings_frm(struct h3c *h3c, const struct buffer *buf,
                         * H3_SETTINGS_ERROR.
                         */
                        h3c->err = H3_ERR_SETTINGS_ERROR;
-                       qcc_report_glitch(h3c->qcc, 1);
                        return -1;
                default:
                        /* MUST be ignored */
@@ -2191,6 +2188,7 @@ static ssize_t h3_rcv_buf(struct qcs *qcs, struct buffer *b, int fin)
                        if (ret < 0) {
                                TRACE_ERROR("error on SETTINGS parsing", H3_EV_RX_FRAME, qcs->qcc->conn, qcs);
                                qcc_set_error(qcs->qcc, h3c->err, 1, muxc_tevt_type_proto_err);
+                               qcc_report_glitch(qcs->qcc, 1);
                                goto err;
                        }
                        h3c->flags |= H3_CF_SETTINGS_RECV;