File bind-CVE-2016-9444.patch of Package bind.3933
Index: bind-9.9.9-P1/lib/dns/message.c
===================================================================
--- bind-9.9.9-P1.orig/lib/dns/message.c 2017-01-07 16:03:08.650917712 +0100
+++ bind-9.9.9-P1/lib/dns/message.c 2017-01-07 16:03:12.670961031 +0100
@@ -1150,6 +1150,63 @@ update(dns_section_t section, dns_rdatac
return (ISC_FALSE);
}
+/*
+ * Check to confirm that all DNSSEC records (DS, NSEC, NSEC3) have
+ * covering RRSIGs.
+ */
+static isc_boolean_t
+auth_signed(dns_namelist_t *section) {
+ dns_name_t *name;
+
+ for (name = ISC_LIST_HEAD(*section);
+ name != NULL;
+ name = ISC_LIST_NEXT(name, link))
+ {
+ int auth_dnssec = 0, auth_rrsig = 0;
+ dns_rdataset_t *rds;
+
+ for (rds = ISC_LIST_HEAD(name->list);
+ rds != NULL;
+ rds = ISC_LIST_NEXT(rds, link))
+ {
+ switch (rds->type) {
+ case dns_rdatatype_ds:
+ auth_dnssec |= 0x1;
+ break;
+ case dns_rdatatype_nsec:
+ auth_dnssec |= 0x2;
+ break;
+ case dns_rdatatype_nsec3:
+ auth_dnssec |= 0x4;
+ break;
+ case dns_rdatatype_rrsig:
+ break;
+ default:
+ continue;
+ }
+
+ switch (rds->covers) {
+ case dns_rdatatype_ds:
+ auth_rrsig |= 0x1;
+ break;
+ case dns_rdatatype_nsec:
+ auth_rrsig |= 0x2;
+ break;
+ case dns_rdatatype_nsec3:
+ auth_rrsig |= 0x4;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (auth_dnssec != auth_rrsig)
+ return (ISC_FALSE);
+ }
+
+ return (ISC_TRUE);
+}
+
static isc_result_t
getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
dns_section_t sectionid, unsigned int options)
@@ -1175,12 +1232,12 @@ getsection(isc_buffer_t *source, dns_mes
best_effort = ISC_TF(options & DNS_MESSAGEPARSE_BESTEFFORT);
seen_problem = ISC_FALSE;
+ section = &msg->sections[sectionid];
+
for (count = 0; count < msg->counts[sectionid]; count++) {
int recstart = source->current;
isc_boolean_t skip_name_search, skip_type_search;
- section = &msg->sections[sectionid];
-
skip_name_search = ISC_FALSE;
skip_type_search = ISC_FALSE;
free_rdataset = ISC_FALSE;
@@ -1565,6 +1622,19 @@ getsection(isc_buffer_t *source, dns_mes
INSIST(free_rdataset == ISC_FALSE);
}
+ /*
+ * If any of DS, NSEC or NSEC3 appeared in the
+ * authority section of a query response without
+ * a covering RRSIG, FORMERR
+ */
+ if (sectionid == DNS_SECTION_AUTHORITY &&
+ msg->opcode == dns_opcode_query &&
+ ((msg->flags & DNS_MESSAGEFLAG_QR) != 0) &&
+ ((msg->flags & DNS_MESSAGEFLAG_TC) == 0) &&
+ !preserve_order &&
+ !auth_signed(section))
+ DO_FORMERR;
+
if (seen_problem)
return (DNS_R_RECOVERABLE);
return (ISC_R_SUCCESS);
Index: bind-9.9.9-P1/lib/dns/resolver.c
===================================================================
--- bind-9.9.9-P1.orig/lib/dns/resolver.c 2017-01-07 16:03:08.654917755 +0100
+++ bind-9.9.9-P1/lib/dns/resolver.c 2017-01-07 16:03:12.674961074 +0100
@@ -5194,13 +5194,9 @@ cache_name(fetchctx_t *fctx, dns_name_t
rdataset->type,
&noqname);
if (tresult == ISC_R_SUCCESS &&
- noqname != NULL) {
- tresult =
- dns_rdataset_addnoqname(
+ noqname != NULL)
+ (void) dns_rdataset_addnoqname(
rdataset, noqname);
- RUNTIME_CHECK(tresult ==
- ISC_R_SUCCESS);
- }
}
addedrdataset = ardataset;
result = dns_db_addrdataset(fctx->cache, node,
@@ -5330,11 +5326,9 @@ cache_name(fetchctx_t *fctx, dns_name_t
tresult = findnoqname(fctx, name,
rdataset->type, &noqname);
if (tresult == ISC_R_SUCCESS &&
- noqname != NULL) {
- tresult = dns_rdataset_addnoqname(
+ noqname != NULL)
+ (void) dns_rdataset_addnoqname(
rdataset, noqname);
- RUNTIME_CHECK(tresult == ISC_R_SUCCESS);
- }
}
/*