diff --git a/CHANGES b/CHANGES
index 1ea58e2f4f..f32714b60c 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,7 @@
+4286. [security] render_ecs errors were mishandled when printing out
+ a OPT record resulting in a assertion failure.
+ (CVE-2015-8705) [RT #41397]
+
4285. [security] Specific APL data could trigger a INSIST.
(CVE-2015-8704) [RT #41396]
diff --git a/doc/arm/notes.xml b/doc/arm/notes.xml
index 60108948b4..7c6afaf4f8 100644
--- a/doc/arm/notes.xml
+++ b/doc/arm/notes.xml
@@ -159,6 +159,14 @@
by Brian Mitchell and is disclosed in CVE-2015-8704. [RT #41396]
+
+
+ render_ecs errors when printing out a OPT record were
+ mishandled resulting in a assertion failure. This flaw
+ was discovered by Brian Mitchell and is disclosed in
+ CVE-2015-8705. [RT #41396]
+
+
New Features
diff --git a/lib/dns/message.c b/lib/dns/message.c
index a30e5edf89..0fa0a0a4d8 100644
--- a/lib/dns/message.c
+++ b/lib/dns/message.c
@@ -3232,7 +3232,7 @@ dns_message_sectiontotext(dns_message_t *msg, dns_section_t section,
}
static isc_result_t
-render_ecs(isc_buffer_t *optbuf, isc_buffer_t *target) {
+render_ecs(isc_buffer_t *ecsbuf, isc_buffer_t *target) {
int i;
char addr[16], addr_text[64];
isc_uint16_t family;
@@ -3242,20 +3242,20 @@ render_ecs(isc_buffer_t *optbuf, isc_buffer_t *target) {
* Note: This routine needs to handle malformed ECS options.
*/
- if (isc_buffer_remaininglength(optbuf) < 4)
+ if (isc_buffer_remaininglength(ecsbuf) < 4)
return (DNS_R_OPTERR);
- family = isc_buffer_getuint16(optbuf);
- addrlen = isc_buffer_getuint8(optbuf);
- scopelen = isc_buffer_getuint8(optbuf);
+ family = isc_buffer_getuint16(ecsbuf);
+ addrlen = isc_buffer_getuint8(ecsbuf);
+ scopelen = isc_buffer_getuint8(ecsbuf);
addrbytes = (addrlen + 7) / 8;
- if (isc_buffer_remaininglength(optbuf) < addrbytes)
+ if (isc_buffer_remaininglength(ecsbuf) < addrbytes)
return (DNS_R_OPTERR);
ADD_STRING(target, ": ");
memset(addr, 0, sizeof(addr));
for (i = 0; i < addrbytes; i ++)
- addr[i] = isc_buffer_getuint8(optbuf);
+ addr[i] = isc_buffer_getuint8(ecsbuf);
if (family == 1)
inet_ntop(AF_INET, addr, addr_text, sizeof(addr_text));
@@ -3358,9 +3358,18 @@ dns_message_pseudosectiontotext(dns_message_t *msg,
} else if (optcode == DNS_OPT_COOKIE) {
ADD_STRING(target, "; COOKIE");
} else if (optcode == DNS_OPT_CLIENT_SUBNET) {
+ isc_buffer_t ecsbuf;
+
ADD_STRING(target, "; CLIENT-SUBNET");
- result = render_ecs(&optbuf, target);
+ isc_buffer_init(&ecsbuf,
+ isc_buffer_current(&optbuf),
+ optlen);
+ isc_buffer_add(&ecsbuf, optlen);
+ result = render_ecs(&ecsbuf, target);
+ if (result == ISC_R_NOSPACE)
+ return (result);
if (result == ISC_R_SUCCESS) {
+ isc_buffer_forward(&optbuf, optlen);
ADD_STRING(target, "\n");
continue;
}