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