From 57a1816faec652d9c7fbd9be48ce25c832be20d9 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Sun, 24 Nov 2019 14:57:53 +0100 Subject: [PATCH] BUG/MAJOR: mux-h2: don't try to decode a response HEADERS frame in idle state Christopher found another issue in the H2 backend implementation that results from a miss in the H2 spec: the processing of a HEADERS frame is always permitted in IDLE state, but this doesn't make sense on the response path! And here when facing such a frame, we try to decode it while we didn't allocate any stream, so we end up trying to fill the idle stream's buffer (read-only) and crash. What we're doing here is that if we get a HEADERS frame in IDLE state from a server, we terminate the connection with a PROTOCOL_ERROR. No such transition seems to be permitted by the spec but it seems to be the only sane solution. This fix must be backported as far as 1.9. Note that in 2.0 and earlier there's no h2_frame_check_vs_state() function, instead the check is inlined in h2_process_demux(). --- src/mux_h2.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/mux_h2.c b/src/mux_h2.c index 24543458b..9502e0551 100644 --- a/src/mux_h2.c +++ b/src/mux_h2.c @@ -2775,6 +2775,13 @@ static int h2_frame_check_vs_state(struct h2c *h2c, struct h2s *h2s) return 0; } + if (h2s->st == H2_SS_IDLE && (h2c->flags & H2_CF_IS_BACK)) { + /* only PUSH_PROMISE would be permitted here */ + h2c_error(h2c, H2_ERR_PROTOCOL_ERROR); + TRACE_DEVEL("leaving in error (idle&back)", H2_EV_RX_FRAME|H2_EV_RX_FHDR|H2_EV_PROTO_ERR, h2c->conn, h2s); + return 0; + } + if (h2s->st == H2_SS_HREM && h2c->dft != H2_FT_WINDOW_UPDATE && h2c->dft != H2_FT_RST_STREAM && h2c->dft != H2_FT_PRIORITY) { /* RFC7540#5.1: any frame other than WU/PRIO/RST in