From 4d73fed57703f561aefd545eda0f3f2c5e69a547 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= Date: Tue, 16 Jan 2018 09:50:45 +0100 Subject: [PATCH] 4858. [security] Addresses could be referenced after being freed in resolver.c, causing an assertion failure. (CVE-2017-3145) [RT #46839] --- lib/dns/resolver.c | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index 860a792..619646f 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -751,7 +751,7 @@ fctx_stoptimer(fetchctx_t *fctx) { * cannot fail in that case. */ result = isc_timer_reset(fctx->timer, isc_timertype_inactive, - NULL, NULL, ISC_TRUE); + NULL, NULL, ISC_TRUE); if (result != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_timer_reset(): %s", @@ -759,7 +759,6 @@ fctx_stoptimer(fetchctx_t *fctx) { } } - static inline isc_result_t fctx_startidletimer(fetchctx_t *fctx, isc_interval_t *interval) { /* @@ -992,7 +991,8 @@ fctx_cleanupfinds(fetchctx_t *fctx) { for (find = ISC_LIST_HEAD(fctx->finds); find != NULL; - find = next_find) { + find = next_find) + { next_find = ISC_LIST_NEXT(find, publink); ISC_LIST_UNLINK(fctx->finds, find, publink); dns_adb_destroyfind(&find); @@ -1008,7 +1008,8 @@ fctx_cleanupaltfinds(fetchctx_t *fctx) { for (find = ISC_LIST_HEAD(fctx->altfinds); find != NULL; - find = next_find) { + find = next_find) + { next_find = ISC_LIST_NEXT(find, publink); ISC_LIST_UNLINK(fctx->altfinds, find, publink); dns_adb_destroyfind(&find); @@ -1024,7 +1025,8 @@ fctx_cleanupforwaddrs(fetchctx_t *fctx) { for (addr = ISC_LIST_HEAD(fctx->forwaddrs); addr != NULL; - addr = next_addr) { + addr = next_addr) + { next_addr = ISC_LIST_NEXT(addr, publink); ISC_LIST_UNLINK(fctx->forwaddrs, addr, publink); dns_adb_freeaddrinfo(fctx->adb, &addr); @@ -1039,7 +1041,8 @@ fctx_cleanupaltaddrs(fetchctx_t *fctx) { for (addr = ISC_LIST_HEAD(fctx->altaddrs); addr != NULL; - addr = next_addr) { + addr = next_addr) + { next_addr = ISC_LIST_NEXT(addr, publink); ISC_LIST_UNLINK(fctx->altaddrs, addr, publink); dns_adb_freeaddrinfo(fctx->adb, &addr); @@ -1047,14 +1050,18 @@ fctx_cleanupaltaddrs(fetchctx_t *fctx) { } static inline void -fctx_stopeverything(fetchctx_t *fctx, isc_boolean_t no_response) { - FCTXTRACE("stopeverything"); +fctx_stopqueries(fetchctx_t *fctx, isc_boolean_t no_response) { + FCTXTRACE("stopqueries"); fctx_cancelqueries(fctx, no_response); + fctx_stoptimer(fctx); +} + +static inline void +fctx_cleanupall(fetchctx_t *fctx) { fctx_cleanupfinds(fctx); fctx_cleanupaltfinds(fctx); fctx_cleanupforwaddrs(fctx); fctx_cleanupaltaddrs(fctx); - fctx_stoptimer(fctx); } static inline void @@ -1184,7 +1191,8 @@ fctx_done(fetchctx_t *fctx, isc_result_t result, int line) { no_response = ISC_FALSE; fctx->reason = NULL; - fctx_stopeverything(fctx, no_response); + + fctx_stopqueries(fctx, no_response); LOCK(&res->buckets[fctx->bucketnum].lock); @@ -3336,11 +3344,12 @@ fctx_doshutdown(isc_task_t *task, isc_event_t *event) { dns_resolver_cancelfetch(fctx->nsfetch); /* - * Shut down anything that is still running on behalf of this - * fetch. To avoid deadlock with the ADB, we must do this - * before we lock the bucket lock. + * Shut down anything still running on behalf of this + * fetch, and clean up finds and addresses. To avoid deadlock + * with the ADB, we must do this before we lock the bucket lock. */ - fctx_stopeverything(fctx, ISC_FALSE); + fctx_stopqueries(fctx, ISC_FALSE); + fctx_cleanupall(fctx); LOCK(&res->buckets[bucketnum].lock); -- 2.14.3