From: Amaury Denoyelle Date: Wed, 9 Apr 2025 12:26:54 +0000 (+0200) Subject: BUG/MINOR: mux-h2: prevent past scheduling with idle connections X-Git-Tag: v3.2-dev11~39 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3ebdd3ae509236af1f19d80cab98b385a751426b;p=thirdparty%2Fhaproxy.git BUG/MINOR: mux-h2: prevent past scheduling with idle connections While reviewing HTTP/2 MUX timeout, it seems there is a possibility that MUX task is requeued via h2c_update_timeout() with an already expired date. This can happens with idle connections on two cases : * first with shut timeout, as timer is not refreshed if already set * second with http-request and keep-alive timers, which are based on idle_start Queuing an already expired task is an undefined behavior. Fix this by using task_wakeup() instead of task_queue() at the end of h2c_update_timeout() if such case occurs. This should be backported up to 2.6. --- diff --git a/src/mux_h2.c b/src/mux_h2.c index 9daa6e7d2..c0dc7c393 100644 --- a/src/mux_h2.c +++ b/src/mux_h2.c @@ -921,6 +921,16 @@ static void h2c_update_timeout(struct h2c *h2c) } else { h2c->task->expire = TICK_ETERNITY; } + + /* Timer may already be expired, in this case it must not be requeued. + * Currently it may happen with idle conn calculation based on shut or + * http-req/ka timeouts. + */ + if (unlikely(tick_is_expired(h2c->task->expire, now_ms))) { + task_wakeup(h2c->task, TASK_WOKEN_TIMER); + goto leave; + } + task_queue(h2c->task); leave: TRACE_LEAVE(H2_EV_H2C_WAKE);