]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
daemon/session: fix an issue with timers
authorVladimír Čunát <vladimir.cunat@nic.cz>
Thu, 22 Jul 2021 16:23:37 +0000 (18:23 +0200)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Wed, 28 Jul 2021 15:10:53 +0000 (17:10 +0200)
The practical problem was also mitigated by libuv >= 1.32.0 (2ee2d46)

NEWS
daemon/session.c

diff --git a/NEWS b/NEWS
index 0c27d6c5acdadbeb3e747cd1c46bce97984f4333..6c4d2b06179550c97c8193fc600a19ed32c6da1a 100644 (file)
--- 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
 --------------------
index a0bf23f3f966678a80b1f465a89a7d288e248dcc..668295ca0ea24284fd9f2aa6567219ad3962bd8e 100644 (file)
@@ -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);
 }