]> git.kaiwu.me - haproxy.git/commitdiff
BUG/MEDIUM: h3: fix BUG_ON() crash with glitch after QPACK dec err
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Mon, 19 Oct 2026 11:48:06 +0000 (13:48 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Tue, 20 Oct 2026 08:51:47 +0000 (10:51 +0200)
This is part of the reworking of glitch reporting in H3 module. The
current patch handles QPACK decoding error when parsing a HEADERS frame.
Function qcc_report_glitch() is now only called after qcc_set_error(),
for both request, response and headers/trailers parsing.

This must be backported up to 3.0.

src/h3.c

index 566819ad358dac50a7a9817d3519f3ae3b9085c5..be9cd7470829ec663ff1be36e670d35208cbf79c 100644 (file)
--- a/src/h3.c
+++ b/src/h3.c
@@ -759,10 +759,8 @@ static ssize_t h3_req_headers_to_htx(struct qcs *qcs, const struct buffer *buf,
                            list, sizeof(list) / sizeof(list[0]));
        if (ret < 0) {
                TRACE_ERROR("QPACK decoding error", H3_EV_RX_FRAME|H3_EV_RX_HDR, qcs->qcc->conn, qcs);
-               if ((qpack_err = qpack_err_decode(ret)) >= 0) {
+               if ((qpack_err = qpack_err_decode(ret)) >= 0)
                        h3c->err = qpack_err;
-                       qcc_report_glitch(qcs->qcc, 1);
-               }
                len = -1;
                goto out;
        }
@@ -1262,10 +1260,8 @@ static ssize_t h3_resp_headers_to_htx(struct qcs *qcs, const struct buffer *buf,
                            list, sizeof(list) / sizeof(list[0]));
        if (ret < 0) {
                TRACE_ERROR("QPACK decoding error", H3_EV_RX_FRAME|H3_EV_RX_HDR, qcs->qcc->conn, qcs);
-               if ((qpack_err = qpack_err_decode(ret)) >= 0) {
+               if ((qpack_err = qpack_err_decode(ret)) >= 0)
                        h3c->err = qpack_err;
-                       qcc_report_glitch(qcs->qcc, 1);
-               }
                len = -1;
                goto out;
        }
@@ -1532,10 +1528,8 @@ static ssize_t h3_trailers_to_htx(struct qcs *qcs, const struct buffer *buf,
                                      tmp, list, sizeof(list) / sizeof(list[0]));
                if (ret < 0) {
                        TRACE_ERROR("QPACK decoding error", H3_EV_RX_FRAME|H3_EV_RX_HDR, qcs->qcc->conn, qcs);
-                       if ((qpack_err = qpack_err_decode(ret)) >= 0) {
+                       if ((qpack_err = qpack_err_decode(ret)) >= 0)
                                h3c->err = qpack_err;
-                               qcc_report_glitch(qcs->qcc, 1);
-                       }
                        len = -1;
                        goto out;
                }
@@ -2137,6 +2131,13 @@ static ssize_t h3_rcv_buf(struct qcs *qcs, struct buffer *b, int fin)
                                ret = h3_trailers_to_htx(qcs, b, flen, last_stream_frame);
                                h3s->st_req = H3S_ST_REQ_TRAILERS;
                        }
+
+                       if (h3c->err) {
+                               qcc_set_error(qcs->qcc, h3c->err, 1, muxc_tevt_type_proto_err);
+                               qcc_report_glitch(qcs->qcc, 1);
+                               goto err;
+                       }
+
                        break;
                case H3_FT_CANCEL_PUSH:
                        if (unlikely(!flen)) {