From afc7cb85c47f89a95554d20fd4a9e11a28b8b4b9 Mon Sep 17 00:00:00 2001 From: Olivier Houchard Date: Mon, 25 Mar 2019 14:08:01 +0100 Subject: [PATCH] BUG/MEDIUM: h2: Follow the same logic in h2_deferred_shut than in h2_snd_buf. In h2_deferred_shut(), don't just set h2s->send_wait to NULL, instead, use the same logic as in h2_snd_buf() and only do so if we successfully sent data (or if we don't want to send them anymore). Setting it to NULL can lead to crashes. This should be backported to 1.9. --- src/mux_h2.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/mux_h2.c b/src/mux_h2.c index f179c4a00..f22e0e1c5 100644 --- a/src/mux_h2.c +++ b/src/mux_h2.c @@ -3220,17 +3220,22 @@ static struct task *h2_deferred_shut(struct task *t, void *ctx, unsigned short s long reason = (long)h2s->wait_event.handle; int ret = 0; + LIST_DEL_INIT(&h2s->sending_list); if (h2s->send_wait) { h2s->send_wait->events &= ~SUB_CALL_UNSUBSCRIBE; - h2s->send_wait = NULL; - LIST_DEL(&h2s->list); - LIST_INIT(&h2s->list); + h2s->send_wait->events |= SUB_RETRY_SEND; } if (reason & 2) ret |= h2_do_shutw(h2s); if (reason & 1) ret |= h2_do_shutr(h2s); + if (!ret) { + /* We're done trying to send, remove ourself from the send_list */ + h2s->send_wait->events &= ~SUB_RETRY_SEND; + h2s->send_wait = NULL; + LIST_DEL_INIT(&h2s->list); + } /* We're no longer trying to send anything, let's destroy the h2s */ if (!ret && (h2s->cs == NULL)) { struct h2c *h2c = h2s->h2c;