From 2135f91d18ae79c5360d32dd8bf10f42aa6ff8b4 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Tue, 7 May 2019 11:17:32 +0200 Subject: [PATCH] BUG/MEDIUM: h2/htx: never leave a trailers block alone with no EOM block If when receiving an H2 response we fail to add an EOM block after too large a trailers block, we must not leave the trailers block alone as it violates the internal assumptions by not being followed by an EOM, even when an error is reported. We must then make sure the error will safely be reported to upper layers and that no attempt will be made to forward partial blocks. This must be backported to 1.9. --- src/mux_h2.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/mux_h2.c b/src/mux_h2.c index 91e826db74..6fb21dd2fd 100644 --- a/src/mux_h2.c +++ b/src/mux_h2.c @@ -3567,11 +3567,19 @@ static int h2c_decode_headers(struct h2c *h2c, struct buffer *rxbuf, uint32_t *f if ((h2c->dff & H2_F_HEADERS_END_STREAM) || (msgf & H2_MSGF_RSP_1XX)) { /* Mark the end of message, either using EOM in HTX or with the * trailing CRLF after the end of trailers. Note that DATA_CHNK - * is not set during headers with END_STREAM. + * is not set during headers with END_STREAM. For HTX trailers, + * we must not leave an HTX trailers block not followed by an + * EOM block, the two must be atomic. Thus if we fail to emit + * the EOM block we must remove the TLR block we've just added. */ if (htx) { - if (!htx_add_endof(htx, HTX_BLK_EOM)) + if (!htx_add_endof(htx, HTX_BLK_EOM)) { + struct htx_blk *tail = htx_get_tail_blk(htx); + + if (tail && htx_get_blk_type(tail) == HTX_BLK_TLR) + htx_remove_blk(htx, tail); goto fail; + } } else if (*flags & H2_SF_DATA_CHNK) { if (!b_putblk(rxbuf, "\r\n", 2))