packages/net/haproxy/patches/0005-BUG-MEDIUM-h2-always-consume-any-trailing-data-after-end-of-output-buffers.patch
Christian Lachner 88fdeb5085 haproxy: Update MEDIUM+ patches for HAProxy v1.8.4
- Add new MEDIUM+ patches (see https://www.haproxy.org/bugs/bugs-1.8.4.html)
- Raise patch-level to 02

Signed-off-by: Christian Lachner <gladiac@gmail.com>
2018-03-16 11:26:28 +01:00

71 lines
2.3 KiB
Diff

From 6fc36785addd45cc76a029a023296def53cff135 Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w@1wt.eu>
Date: Tue, 27 Feb 2018 15:37:25 +0100
Subject: [PATCH] BUG/MEDIUM: h2: always consume any trailing data after end
of output buffers
In case a stream tries to emit more data than advertised by the chunks
or content-length headers, the extra data remains in the channel's output
buffer until the channel's timeout expires. It can easily happen when
sending malformed error files making use of a wrong content-length or
having extra CRLFs after the empty chunk. It may also be possible to
forge such a bad response using Lua.
The H1 to H2 encoder must protect itself against this by marking the data
presented to it as consumed if it decides to discard them, so that the
sending stream doesn't wait for the timeout to trigger.
The visible effect of this problem is a huge memory usage and a high
concurrent connection count during benchmarks when using such bad data
(a typical place where this easily happens).
This fix must be backported to 1.8.
(cherry picked from commit 35a62705df65632e2717ae0d20a93e0cb3f8f163)
Signed-off-by: Willy Tarreau <w@1wt.eu>
---
src/mux_h2.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/src/mux_h2.c b/src/mux_h2.c
index caae041..4303a06 100644
--- a/src/mux_h2.c
+++ b/src/mux_h2.c
@@ -3020,6 +3020,9 @@ static int h2s_frt_make_resp_headers(struct h2s *h2s, struct buffer *buf)
* body or directly end in TRL2.
*/
if (es_now) {
+ // trim any possibly pending data (eg: inconsistent content-length)
+ bo_del(buf, buf->o);
+
h1m->state = HTTP_MSG_DONE;
h2s->flags |= H2_SF_ES_SENT;
if (h2s->st == H2_SS_OPEN)
@@ -3269,8 +3272,12 @@ static int h2s_frt_make_resp_data(struct h2s *h2s, struct buffer *buf)
else
h2c_stream_close(h2c, h2s);
- if (!(h1m->flags & H1_MF_CHNK))
+ if (!(h1m->flags & H1_MF_CHNK)) {
+ // trim any possibly pending data (eg: inconsistent content-length)
+ bo_del(buf, buf->o);
+
h1m->state = HTTP_MSG_DONE;
+ }
h2s->flags |= H2_SF_ES_SENT;
}
@@ -3319,6 +3326,10 @@ static int h2_snd_buf(struct conn_stream *cs, struct buffer *buf, int flags)
}
total += count;
bo_del(buf, count);
+
+ // trim any possibly pending data (eg: extra CR-LF, ...)
+ bo_del(buf, buf->o);
+
h2s->res.state = HTTP_MSG_DONE;
break;
}
--
1.7.10.4