]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: h2: Make sure we set send_list to NULL in h2_detach().
authorOlivier Houchard <ohouchard@haproxy.com>
Thu, 9 May 2019 11:24:08 +0000 (13:24 +0200)
committerOlivier Houchard <cognet@ci0.org>
Thu, 9 May 2019 11:26:48 +0000 (13:26 +0200)
In h2_detach(), if we still have a send_wait pointer, because we woke the
tasklet up, but it hasn't ran yet, explicitely set send_wait to NULL after
we removed the tasklet from the task list.
Failure to do so may lead to crashes if the h2s isn't immediately destroyed,
because we considered there were still something to send.

This should be backported to 1.9.

src/mux_h2.c

index 6105f1bce1043211ab048986914b5d8d386b1587..6a8a762a25455f6ef0f6f97dbcdf42294657c120 100644 (file)
@@ -3052,6 +3052,19 @@ static void h2_detach(struct conn_stream *cs)
            h2s->send_wait != &h2s->wait_event) {
                task_remove_from_tasklet_list((struct task *)h2s->send_wait->task);
                LIST_DEL_INIT(&h2s->sending_list);
+               /*
+                * At this point, the stream_interface is supposed to have called
+                * h2_unsubscribe(), so the only way there's still a
+                * subscription that came from the stream_interface (as we
+                * can subscribe ourself, in h2_do_shutw() and h2_do_shutr(),
+                * without the stream_interface involved) is that we subscribed
+                * for sending, we woke the tasklet up and removed the
+                * SUB_RETRY_SEND flag, so the stream_interface would not
+                * know it has to unsubscribe for send, but the tasklet hasn't
+                * run yet. Make sure to handle that by explicitely setting
+                * send_wait to NULL, as nothing else will do it for us.
+                */
+               h2s->send_wait = NULL;
        }
 
        sess = h2s->sess;