From: Willy Tarreau Date: Thu, 22 Mar 2018 16:37:05 +0000 (+0100) Subject: BUG/MINOR: h2: ensure we can never send an RST_STREAM in response to an RST_STREAM X-Git-Tag: v1.9-dev1~350 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8adae7c15ffb5df8fcbb41496735fef25d6c4df3;p=thirdparty%2Fhaproxy.git BUG/MINOR: h2: ensure we can never send an RST_STREAM in response to an RST_STREAM There are some corner cases where this could happen by accident. Since the spec explicitly forbids this (RFC7540#5.4.2), let's add a test in the two only functions which make the RST to avoid this. Thanks to user klzgrad for reporting this problem. Usually it is expected to be harmless but may result in browsers issuing a warning. This fix must be backported to 1.8. --- diff --git a/src/mux_h2.c b/src/mux_h2.c index d15b0e33b7..7b2f538189 100644 --- a/src/mux_h2.c +++ b/src/mux_h2.c @@ -844,6 +844,14 @@ static int h2s_send_rst_stream(struct h2c *h2c, struct h2s *h2s) if (!h2s || h2s->st == H2_SS_CLOSED) return 1; + /* RFC7540#5.4.2: To avoid looping, an endpoint MUST NOT send a + * RST_STREAM in response to a RST_STREAM frame. + */ + if (h2c->dft == H2_FT_RST_STREAM) { + ret = 1; + goto ignore; + } + if (h2c_mux_busy(h2c, h2s)) { h2s->flags |= H2_SF_BLK_MBUSY; return 0; @@ -874,6 +882,7 @@ static int h2s_send_rst_stream(struct h2c *h2c, struct h2s *h2s) } } + ignore: h2s->flags |= H2_SF_RST_SENT; h2s_close(h2s); return ret; @@ -896,6 +905,14 @@ static int h2c_send_rst_stream(struct h2c *h2c, struct h2s *h2s) char str[13]; int ret; + /* RFC7540#5.4.2: To avoid looping, an endpoint MUST NOT send a + * RST_STREAM in response to a RST_STREAM frame. + */ + if (h2c->dft == H2_FT_RST_STREAM) { + ret = 1; + goto ignore; + } + if (h2c_mux_busy(h2c, h2s)) { h2c->flags |= H2_CF_DEM_MBUSY; return 0; @@ -928,6 +945,7 @@ static int h2c_send_rst_stream(struct h2c *h2c, struct h2s *h2s) } } + ignore: if (h2s->st > H2_SS_IDLE && h2s->st < H2_SS_CLOSED) { h2s->flags |= H2_SF_RST_SENT; h2s_close(h2s);