]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: h3: reject RESET_STREAM received for control stream
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Mon, 30 Jan 2023 11:13:22 +0000 (12:13 +0100)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Mon, 30 Jan 2023 15:16:46 +0000 (16:16 +0100)
This commit is similar to the previous one. It reports an error if a
RESET_STREAM is received for the remote control stream. This will
generate a CONNECTION_CLOSE with H3_CLOSED_CRITICAL_STREAM error.

Note that contrary to the previous bug related to STOP_SENDING, this bug
was not encountered in real environment. As such, it is labelled as
MINOR. However, it could triggered the same crash as the previous patch.

This should be backported up to 2.6.

src/h3.c
src/mux_quic.c

index ea512a40432d7dafabaf9dbda7eb7a33d8085b8f..616110b723a2a5468a622a4546b2b744e5eac55c 100644 (file)
--- a/src/h3.c
+++ b/src/h3.c
@@ -1626,7 +1626,7 @@ static int h3_close(struct qcs *qcs, enum qcc_app_ops_close_side side)
         * control stream is closed at any point, this MUST be treated
         * as a connection error of type H3_CLOSED_CRITICAL_STREAM.
         */
-       if (qcs == h3c->ctrl_strm) {
+       if (qcs == h3c->ctrl_strm || h3s->type == H3S_T_CTRL) {
                TRACE_ERROR("closure detected on control stream", H3_EV_H3S_END, qcs->qcc, qcs);
                qcc_emit_cc_app(qcs->qcc, H3_CLOSED_CRITICAL_STREAM, 1);
                return 1;
index cae22df1ffbb51b405bdfebc14ea1145f093d8c7..98737367e34e315ad0843e11d5f39a4f4d6e576e 100644 (file)
@@ -1155,6 +1155,13 @@ int qcc_recv_reset_stream(struct qcc *qcc, uint64_t id, uint64_t err, uint64_t f
        TRACE_PROTO("receiving RESET_STREAM", QMUX_EV_QCC_RECV|QMUX_EV_QCS_RECV, qcc->conn, qcs);
        qcs_idle_open(qcs);
 
+       if (qcc->app_ops->close) {
+               if (qcc->app_ops->close(qcs, QCC_APP_OPS_CLOSE_SIDE_RD)) {
+                       TRACE_ERROR("closure rejected by app layer", QMUX_EV_QCC_RECV|QMUX_EV_QCS_RECV, qcc->conn, qcs);
+                       goto out;
+               }
+       }
+
        if (qcs->rx.offset_max > final_size ||
            ((qcs->flags & QC_SF_SIZE_KNOWN) && qcs->rx.offset_max != final_size)) {
                TRACE_ERROR("final size error on RESET_STREAM", QMUX_EV_QCC_RECV|QMUX_EV_QCS_RECV, qcc->conn, qcs);