From: Vladimír Čunát Date: Thu, 22 Jul 2021 16:23:37 +0000 (+0200) Subject: daemon/session: fix an issue with timers X-Git-Tag: v5.4.0~3^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=91ce241ac548574014e68d2e036afa83137448e2;p=thirdparty%2Fknot-resolver.git daemon/session: fix an issue with timers The practical problem was also mitigated by libuv >= 1.32.0 (2ee2d46) --- diff --git a/NEWS b/NEWS index 0c27d6c5a..6c4d2b061 100644 --- a/NEWS +++ b/NEWS @@ -10,6 +10,7 @@ Bugfixes - trust_anchors.set_insecure: improve precision (#673, !1177) - plug memory leaks related to TCP (!1182) - policy.FLAGS: fix not applying properly in edge cases (!1179) +- fix a crash with older libuv inside timer processing (!1195) Incompatible changes -------------------- diff --git a/daemon/session.c b/daemon/session.c index a0bf23f3f..668295ca0 100644 --- a/daemon/session.c +++ b/daemon/session.c @@ -503,18 +503,24 @@ int session_timer_start(struct session *session, uv_timer_cb cb, uint64_t timeout, uint64_t repeat) { uv_timer_t *timer = &session->timeout; + // Session might be closing and get here e.g. through a late on_send callback. + const bool is_closing = uv_is_closing((uv_handle_t *)timer); + if (is_closing || kr_fails_assert(is_closing == session->sflags.closing)) + return kr_error(EINVAL); + if (kr_fails_assert(timer->data == session)) return kr_error(EINVAL); int ret = uv_timer_start(timer, cb, timeout, repeat); if (ret != 0) { uv_timer_stop(timer); - return kr_error(ENOMEM); + return kr_error(ret); } - return 0; + return kr_ok(); } int session_timer_restart(struct session *session) { + kr_require(!uv_is_closing((uv_handle_t *)&session->timeout)); return uv_timer_again(&session->timeout); }