From a8519357c500519a9022204f5637f03c26047c0d Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Tue, 18 Dec 2018 16:44:28 +0100 Subject: [PATCH] BUG/MEDIUM: mux-h2: report asynchronous errors in h2_wake_some_streams() This function is called when dealing with a connection error or a GOAWAY frame. It used to report a synchronous error instead of an asycnhronous error, which can lead to data truncation since whatever is still available in the rxbuf will be ignored. Let's correctly use CS_FL_ERR_PENDING instead and only fall back to CS_FL_ERROR if CS_FL_EOS was already delivered. No backport is needed. --- src/mux_h2.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/mux_h2.c b/src/mux_h2.c index 4c494d565a..a76ca0f3fd 100644 --- a/src/mux_h2.c +++ b/src/mux_h2.c @@ -1241,7 +1241,7 @@ static void h2_wake_some_streams(struct h2c *h2c, int last, uint32_t flags) struct h2s *h2s; if (h2c->st0 >= H2_CS_ERROR || h2c->conn->flags & CO_FL_ERROR) - flags |= CS_FL_ERROR; + flags |= CS_FL_ERR_PENDING; if (conn_xprt_read0_pending(h2c->conn)) flags |= CS_FL_REOS; @@ -1260,6 +1260,9 @@ static void h2_wake_some_streams(struct h2c *h2c, int last, uint32_t flags) } h2s->cs->flags |= flags; + if ((flags & CS_FL_ERR_PENDING) && (h2s->cs->flags & CS_FL_EOS)) + h2s->cs->flags |= CS_FL_ERROR; + if (h2s->recv_wait) { struct wait_event *sw = h2s->recv_wait; sw->wait_reason &= ~SUB_CAN_RECV; @@ -1268,7 +1271,7 @@ static void h2_wake_some_streams(struct h2c *h2c, int last, uint32_t flags) } else if (h2s->cs->data_cb->wake != NULL) h2s->cs->data_cb->wake(h2s->cs); - if (flags & CS_FL_ERROR && h2s->st < H2_SS_ERROR) + if (flags & CS_FL_ERR_PENDING && h2s->st < H2_SS_ERROR) h2s->st = H2_SS_ERROR; else if (flags & CS_FL_REOS && h2s->st == H2_SS_OPEN) h2s->st = H2_SS_HREM;