From e7e15d1302b26a96fa0a5307d6f2cb0d8ad4ea63 Mon Sep 17 00:00:00 2001
From: Mark Andrews <marka@isc.org>
Date: Thu, 18 Feb 2016 12:11:27 +1100
Subject: [PATCH] 4318. [security] Malformed control messages can
trigger assertions in named and rndc. (CVE-2016-1285) [RT #41666]

(cherry picked from commit a2b15b3305acd52179e6f3dc7d073b07fbc40b8e)

Hand applied Changelog changes.

CVE: CVE-2016-1285
Upstream-Status: Backport

Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com>
---
diff -ruN a/bin/named/control.c b/bin/named/control.c
--- a/bin/named/control.c	2015-08-15 02:28:49.000000000 +0200
+++ b/bin/named/control.c	2016-04-11 09:38:20.940827528 +0200
@@ -69,7 +69,7 @@
 #endif
 
 	data = isccc_alist_lookup(message, "_data");
-	if (data == NULL) {
+	if (!isccc_alist_alistp(data)) {
 		/*
 		 * No data section.
 		 */
diff -ruN a/bin/named/controlconf.c b/bin/named/controlconf.c
--- a/bin/named/controlconf.c	2015-08-15 02:28:49.000000000 +0200
+++ b/bin/named/controlconf.c	2016-04-11 09:38:20.944827355 +0200
@@ -402,7 +402,7 @@
 	 * Limit exposure to replay attacks.
 	 */
 	_ctrl = isccc_alist_lookup(request, "_ctrl");
-	if (_ctrl == NULL) {
+	if (!isccc_alist_alistp(_ctrl)) {
 		log_invalid(&conn->ccmsg, ISC_R_FAILURE);
 		goto cleanup_request;
 	}
diff -ruN a/bin/rndc/rndc.c b/bin/rndc/rndc.c
--- a/bin/rndc/rndc.c	2015-08-15 02:28:49.000000000 +0200
+++ b/bin/rndc/rndc.c	2016-04-11 09:38:20.944827355 +0200
@@ -254,8 +254,8 @@
 	   isccc_cc_fromwire(&source, &response, algorithm, &secret));
 
 	data = isccc_alist_lookup(response, "_data");
-	if (data == NULL)
-		fatal("no data section in response");
+	if (!isccc_alist_alistp(data))
+		fatal("bad or missing data section in response");
 	result = isccc_cc_lookupstring(data, "err", &errormsg);
 	if (result == ISC_R_SUCCESS) {
 		failed = ISC_TRUE;
@@ -320,8 +320,8 @@
 	   isccc_cc_fromwire(&source, &response, algorithm, &secret));
 
 	_ctrl = isccc_alist_lookup(response, "_ctrl");
-	if (_ctrl == NULL)
-		fatal("_ctrl section missing");
+	if (!isccc_alist_alistp(_ctrl))
+		fatal("bad or missing ctrl section in response");
 	nonce = 0;
 	if (isccc_cc_lookupuint32(_ctrl, "_nonce", &nonce) != ISC_R_SUCCESS)
 		nonce = 0;
diff -ruN a/CHANGES b/CHANGES
--- a/CHANGES	2016-04-11 09:36:08.546578759 +0200
+++ b/CHANGES	2016-04-11 09:39:59.356552273 +0200
@@ -1,3 +1,6 @@
+4318.  [security]      Malformed control messages can trigger assertions
+                       in named and rndc. (CVE-2016-1285) [RT #41666]
+
 4146.  [bug]           Address reference leak that could prevent a clean
                        shutdown. [RT #37125]
 
diff -ruN a/lib/isccc/cc.c b/lib/isccc/cc.c
--- a/lib/isccc/cc.c	2015-08-15 02:28:49.000000000 +0200
+++ b/lib/isccc/cc.c	2016-04-11 09:38:20.944827355 +0200
@@ -403,13 +403,13 @@
 	 * Extract digest.
 	 */
 	_auth = isccc_alist_lookup(alist, "_auth");
-	if (_auth == NULL)
+	if (!isccc_alist_alistp(_auth))
 		return (ISC_R_FAILURE);
 	if (algorithm == ISCCC_ALG_HMACMD5)
 		hmac = isccc_alist_lookup(_auth, "hmd5");
 	else
 		hmac = isccc_alist_lookup(_auth, "hsha");
-	if (hmac == NULL)
+	if (!isccc_sexpr_binaryp(hmac))
 		return (ISC_R_FAILURE);
 	/*
 	 * Compute digest.
@@ -728,7 +728,7 @@
 	REQUIRE(ackp != NULL && *ackp == NULL);
 
 	_ctrl = isccc_alist_lookup(message, "_ctrl");
-	if (_ctrl == NULL ||
+	if (!isccc_alist_alistp(_ctrl) ||
 	    isccc_cc_lookupuint32(_ctrl, "_ser", &serial) != ISC_R_SUCCESS ||
 	    isccc_cc_lookupuint32(_ctrl, "_tim", &t) != ISC_R_SUCCESS)
 		return (ISC_R_FAILURE);
@@ -773,7 +773,7 @@
 	isccc_sexpr_t *_ctrl;
 
 	_ctrl = isccc_alist_lookup(message, "_ctrl");
-	if (_ctrl == NULL)
+	if (!isccc_alist_alistp(_ctrl))
 		return (ISC_FALSE);
 	if (isccc_cc_lookupstring(_ctrl, "_ack", NULL) == ISC_R_SUCCESS)
 		return (ISC_TRUE);
@@ -786,7 +786,7 @@
 	isccc_sexpr_t *_ctrl;
 
 	_ctrl = isccc_alist_lookup(message, "_ctrl");
-	if (_ctrl == NULL)
+	if (!isccc_alist_alistp(_ctrl))
 		return (ISC_FALSE);
 	if (isccc_cc_lookupstring(_ctrl, "_rpl", NULL) == ISC_R_SUCCESS)
 		return (ISC_TRUE);
@@ -806,7 +806,7 @@
 
 	_ctrl = isccc_alist_lookup(message, "_ctrl");
 	_data = isccc_alist_lookup(message, "_data");
-	if (_ctrl == NULL || _data == NULL ||
+	if (!isccc_alist_alistp(_ctrl) || !isccc_alist_alistp(_data) ||
 	    isccc_cc_lookupuint32(_ctrl, "_ser", &serial) != ISC_R_SUCCESS ||
 	    isccc_cc_lookupstring(_data, "type", &type) != ISC_R_SUCCESS)
 		return (ISC_R_FAILURE);
@@ -995,7 +995,7 @@
 	isccc_sexpr_t *_ctrl;
 
 	_ctrl = isccc_alist_lookup(message, "_ctrl");
-	if (_ctrl == NULL ||
+	if (!isccc_alist_alistp(_ctrl) ||
 	    isccc_cc_lookupstring(_ctrl, "_ser", &_ser) != ISC_R_SUCCESS ||
 	    isccc_cc_lookupstring(_ctrl, "_tim", &_tim) != ISC_R_SUCCESS)
 		return (ISC_R_FAILURE);