From: Tony Finch Date: Thu, 30 Mar 2023 16:56:08 +0000 (+0100) Subject: Fix a crash when dig or host receive a signal X-Git-Tag: v9.19.12~45^2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=194621a74eaaa5834533a1602078112916fdabe6;p=thirdparty%2Fbind9.git Fix a crash when dig or host receive a signal When the loopmanager is shutting down following a signal, `dig` and `host` should stop cleanly. Before this commit they were oblivious to ISC_R_SHUTTINGDOWN. The `isc_signal` callbacks now report this kind of mistake with a stack backtrace. --- diff --git a/CHANGES b/CHANGES index 211adb7403b..3a35753cdb0 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +6134. [bug] Fix a crash when dig or host receive a signal. + [GL #3970] + 6133. [cleanup] Refactor the isc_job_run() to not make any allocations by embedding isc_job_t into callback argument, and running it directly. As a side-effect, isc_async_run diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c index 97b53f1b2fa..e36023e2989 100644 --- a/bin/dig/dighost.c +++ b/bin/dig/dighost.c @@ -3911,7 +3911,9 @@ recv_done(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region, lookup_attach(query->lookup, &l); - if (eresult == ISC_R_CANCELED || query->canceled) { + if (eresult == ISC_R_CANCELED || eresult == ISC_R_SHUTTINGDOWN || + query->canceled) + { debug("recv_done: cancel"); isc_nmhandle_detach(&query->readhandle); if (!query->canceled) { diff --git a/lib/isc/loop_p.h b/lib/isc/loop_p.h index 8810a366197..9594a0f306a 100644 --- a/lib/isc/loop_p.h +++ b/lib/isc/loop_p.h @@ -121,7 +121,11 @@ struct isc_loopmgr { /* * Signal Handler */ +#define SIGNAL_MAGIC ISC_MAGIC('S', 'I', 'G', ' ') +#define VALID_SIGNAL(t) ISC_MAGIC_VALID(t, SIGNAL_MAGIC) + struct isc_signal { + int magic; uv_signal_t signal; isc_loop_t *loop; isc_signal_cb cb; diff --git a/lib/isc/signal.c b/lib/isc/signal.c index 69c75412889..5181f15af18 100644 --- a/lib/isc/signal.c +++ b/lib/isc/signal.c @@ -30,6 +30,7 @@ isc_signal_new(isc_loopmgr_t *loopmgr, isc_signal_cb cb, void *cbarg, signal = isc_mem_get(isc_loop_getmctx(loop), sizeof(*signal)); *signal = (isc_signal_t){ + .magic = SIGNAL_MAGIC, .cb = cb, .cbarg = cbarg, .signum = signum, @@ -48,18 +49,22 @@ isc_signal_new(isc_loopmgr_t *loopmgr, isc_signal_cb cb, void *cbarg, static void isc__signal_destroy_cb(uv_handle_t *handle) { isc_signal_t *signal = uv_handle_get_data(handle); - isc_loop_t *loop = signal->loop; + isc_loop_t *loop = NULL; - isc_mem_put(loop->mctx, signal, sizeof(*signal)); + REQUIRE(VALID_SIGNAL(signal)); + loop = signal->loop; + isc_mem_put(loop->mctx, signal, sizeof(*signal)); isc_loop_detach(&loop); } void isc_signal_destroy(isc_signal_t **signalp) { - isc_signal_t *signal; + isc_signal_t *signal = NULL; + + REQUIRE(signalp != NULL); + REQUIRE(VALID_SIGNAL(*signalp)); - REQUIRE(signalp != NULL && *signalp != NULL); signal = *signalp; *signalp = NULL; @@ -68,7 +73,10 @@ isc_signal_destroy(isc_signal_t **signalp) { void isc_signal_stop(isc_signal_t *signal) { - int r = uv_signal_stop(&signal->signal); + int r; + + REQUIRE(VALID_SIGNAL(signal)); + r = uv_signal_stop(&signal->signal); UV_RUNTIME_CHECK(uv_signal_stop, r); } @@ -76,6 +84,7 @@ static void isc__signal_cb(uv_signal_t *handle, int signum) { isc_signal_t *signal = uv_handle_get_data((uv_handle_t *)handle); + REQUIRE(VALID_SIGNAL(signal)); REQUIRE(signum == signal->signum); signal->cb(signal->cbarg, signum); @@ -83,7 +92,9 @@ isc__signal_cb(uv_signal_t *handle, int signum) { void isc_signal_start(isc_signal_t *signal) { - int r = uv_signal_start(&signal->signal, isc__signal_cb, - signal->signum); + int r; + + REQUIRE(VALID_SIGNAL(signal)); + r = uv_signal_start(&signal->signal, isc__signal_cb, signal->signum); UV_RUNTIME_CHECK(uv_signal_start, r); }