]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: h2: properly check PRIORITY frames
authorWilly Tarreau <w@1wt.eu>
Sun, 3 Dec 2017 18:46:19 +0000 (19:46 +0100)
committerWilly Tarreau <w@1wt.eu>
Sun, 3 Dec 2017 20:08:43 +0000 (21:08 +0100)
We don't use them right now but it's better to ensure they're properly
checked. This removes another 3 warnings in h2spec.

To backport to 1.8.

src/mux_h2.c

index a7e0c44e516aff88bea4032566b24c681bf2f5b4..35899d32d5b8584ab13c38e58fadad84869ddde3 100644 (file)
@@ -1422,6 +1422,40 @@ static int h2c_handle_goaway(struct h2c *h2c)
        return 0;
 }
 
+/* processes a PRIORITY frame, and either skips it or rejects if it is
+ * invalid. Returns > 0 on success or zero on missing data. It may return
+ * an error in h2c. Described in RFC7540#6.3.
+ */
+static int h2c_handle_priority(struct h2c *h2c)
+{
+       int error;
+
+       if (h2c->dsi == 0) {
+               error = H2_ERR_PROTOCOL_ERROR;
+               goto conn_err;
+       }
+
+       if (h2c->dfl != 5) {
+               error = H2_ERR_FRAME_SIZE_ERROR;
+               goto conn_err;
+       }
+
+       /* process full frame only */
+       if (h2c->dbuf->i < h2c->dfl)
+               return 0;
+
+       if (h2_get_n32(h2c->dbuf, 0) == h2c->dsi) {
+               /* 7540#5.3 : can't depend on itself */
+               error = H2_ERR_PROTOCOL_ERROR;
+               goto conn_err;
+       }
+       return 1;
+
+ conn_err:
+       h2c_error(h2c, error);
+       return 0;
+}
+
 /* processes an RST_STREAM frame, and sets the 32-bit error code on the stream.
  * Returns > 0 on success or zero on missing data. It may return an error in
  * h2c. Described in RFC7540#6.4.
@@ -1809,6 +1843,11 @@ static void h2_process_demux(struct h2c *h2c)
                                ret = h2c_send_strm_wu(h2c);
                        break;
 
+               case H2_FT_PRIORITY:
+                       if (h2c->st0 == H2_CS_FRAME_P)
+                               ret = h2c_handle_priority(h2c);
+                       break;
+
                case H2_FT_RST_STREAM:
                        if (h2c->st0 == H2_CS_FRAME_P)
                                ret = h2c_handle_rst_stream(h2c, h2s);