You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
193 lines
6.2 KiB
193 lines
6.2 KiB
From f05af77f32742b8e601d766e1f2fe6a480c7e735 Mon Sep 17 00:00:00 2001 |
|
From: rpm-build <rpm-build> |
|
Date: Wed, 8 Feb 2017 12:23:20 +0100 |
|
Subject: [PATCH] 4557. [security] Combining dns64 and rpz can result in |
|
dereferencing a NULL pointer (read). (CVE-2017-3135) |
|
[RT#44434] |
|
|
|
--- |
|
bin/named/query.c | 59 +++++++++++++++++++++++++----------------------------- |
|
lib/dns/message.c | 6 +++--- |
|
lib/dns/rdataset.c | 1 + |
|
3 files changed, 31 insertions(+), 35 deletions(-) |
|
|
|
diff --git a/bin/named/query.c b/bin/named/query.c |
|
index 1975dfc..f60078b 100644 |
|
--- a/bin/named/query.c |
|
+++ b/bin/named/query.c |
|
@@ -5591,9 +5591,10 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) |
|
dns_rpz_st_t *rpz_st; |
|
isc_boolean_t resuming; |
|
int line = -1; |
|
- isc_boolean_t dns64_exclude, dns64; |
|
+ isc_boolean_t dns64_exclude, dns64, rpz; |
|
dns_clientinfomethods_t cm; |
|
dns_clientinfo_t ci; |
|
+ dns_name_t *rpzqname; |
|
|
|
CTRACE("query_find"); |
|
|
|
@@ -5619,7 +5620,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) |
|
zone = NULL; |
|
need_wildcardproof = ISC_FALSE; |
|
empty_wild = ISC_FALSE; |
|
- dns64_exclude = dns64 = ISC_FALSE; |
|
+ dns64_exclude = dns64 = rpz = ISC_FALSE; |
|
options = 0; |
|
resuming = ISC_FALSE; |
|
is_zone = ISC_FALSE; |
|
@@ -5736,6 +5737,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) |
|
authoritative = ISC_FALSE; |
|
version = NULL; |
|
need_wildcardproof = ISC_FALSE; |
|
+ rpz = ISC_FALSE; |
|
|
|
if (client->view->checknames && |
|
!dns_rdata_checkowner(client->query.qname, |
|
@@ -5860,11 +5862,29 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) |
|
} |
|
|
|
/* |
|
- * Now look for an answer in the database. |
|
+ * Now look for an answer in the database. If this is a dns64 |
|
+ * AAAA lookup on a rpz database adjust the qname. |
|
*/ |
|
- result = dns_db_findext(db, client->query.qname, version, type, |
|
+ if (dns64 && rpz) |
|
+ rpzqname = client->query.rpz_st->qname; |
|
+ else |
|
+ rpzqname = client->query.qname; |
|
+ |
|
+ result = dns_db_findext(db, rpzqname, version, type, |
|
client->query.dboptions, client->now, |
|
&node, fname, &cm, &ci, rdataset, sigrdataset); |
|
+ /* |
|
+ * Fixup fname and sigrdataset. |
|
+ */ |
|
+ if (dns64 && rpz) { |
|
+ isc_result_t rresult; |
|
+ |
|
+ rresult = dns_name_copy(client->query.qname, fname, NULL); |
|
+ RUNTIME_CHECK(rresult == ISC_R_SUCCESS); |
|
+ if (sigrdataset != NULL && |
|
+ dns_rdataset_isassociated(sigrdataset)) |
|
+ dns_rdataset_disassociate(sigrdataset); |
|
+ } |
|
|
|
resume: |
|
CTRACE("query_find: resume"); |
|
@@ -6067,9 +6087,11 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) |
|
switch (rpz_st->m.policy) { |
|
case DNS_RPZ_POLICY_NXDOMAIN: |
|
result = DNS_R_NXDOMAIN; |
|
+ rpz = ISC_TRUE; |
|
break; |
|
case DNS_RPZ_POLICY_NODATA: |
|
result = DNS_R_NXRRSET; |
|
+ rpz = ISC_TRUE; |
|
break; |
|
case DNS_RPZ_POLICY_RECORD: |
|
result = rpz_st->m.result; |
|
@@ -6089,6 +6111,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) |
|
rdataset->ttl = ISC_MIN(rdataset->ttl, |
|
rpz_st->m.ttl); |
|
} |
|
+ rpz = ISC_TRUE; |
|
break; |
|
case DNS_RPZ_POLICY_WILDCNAME: |
|
result = dns_rdataset_first(rdataset); |
|
@@ -6130,7 +6153,6 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) |
|
client->attributes &= ~(NS_CLIENTATTR_WANTDNSSEC | |
|
DNS_MESSAGEFLAG_AD); |
|
query_putrdataset(client, &sigrdataset); |
|
- rpz_st->q.is_zone = is_zone; |
|
is_zone = ISC_TRUE; |
|
rpz_log_rewrite(client, ISC_FALSE, rpz_st->m.policy, |
|
rpz_st->m.type, zone, rpz_st->qname); |
|
@@ -6509,15 +6531,6 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) |
|
rdataset = NULL; |
|
sigrdataset = NULL; |
|
type = qtype = dns_rdatatype_a; |
|
- rpz_st = client->query.rpz_st; |
|
- if (rpz_st != NULL) { |
|
- /* |
|
- * Arrange for RPZ rewriting of any A records. |
|
- */ |
|
- if ((rpz_st->state & DNS_RPZ_REWRITTEN) != 0) |
|
- is_zone = rpz_st->q.is_zone; |
|
- rpz_st_clear(client); |
|
- } |
|
dns64 = ISC_TRUE; |
|
goto db_find; |
|
} |
|
@@ -6786,15 +6799,6 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) |
|
sigrdataset = NULL; |
|
fname = NULL; |
|
type = qtype = dns_rdatatype_a; |
|
- rpz_st = client->query.rpz_st; |
|
- if (rpz_st != NULL) { |
|
- /* |
|
- * Arrange for RPZ rewriting of any A records. |
|
- */ |
|
- if ((rpz_st->state & DNS_RPZ_REWRITTEN) != 0) |
|
- is_zone = rpz_st->q.is_zone; |
|
- rpz_st_clear(client); |
|
- } |
|
dns64 = ISC_TRUE; |
|
goto db_find; |
|
} |
|
@@ -7296,15 +7300,6 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) |
|
rdataset = NULL; |
|
sigrdataset = NULL; |
|
type = qtype = dns_rdatatype_a; |
|
- rpz_st = client->query.rpz_st; |
|
- if (rpz_st != NULL) { |
|
- /* |
|
- * Arrange for RPZ rewriting of any A records. |
|
- */ |
|
- if ((rpz_st->state & DNS_RPZ_REWRITTEN) != 0) |
|
- is_zone = rpz_st->q.is_zone; |
|
- rpz_st_clear(client); |
|
- } |
|
dns64_exclude = dns64 = ISC_TRUE; |
|
goto db_find; |
|
} |
|
diff --git a/lib/dns/message.c b/lib/dns/message.c |
|
index 884107e..1417067 100644 |
|
--- a/lib/dns/message.c |
|
+++ b/lib/dns/message.c |
|
@@ -1234,8 +1234,8 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, |
|
{ |
|
isc_region_t r; |
|
unsigned int count, rdatalen; |
|
- dns_name_t *name; |
|
- dns_name_t *name2; |
|
+ dns_name_t *name = NULL; |
|
+ dns_name_t *name2 = NULL; |
|
dns_offsets_t *offsets; |
|
dns_rdataset_t *rdataset; |
|
dns_rdatalist_t *rdatalist; |
|
@@ -1245,7 +1245,7 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, |
|
dns_rdata_t *rdata; |
|
dns_ttl_t ttl; |
|
dns_namelist_t *section; |
|
- isc_boolean_t free_name, free_rdataset; |
|
+ isc_boolean_t free_name = ISC_FALSE, free_rdataset = ISC_FALSE; |
|
isc_boolean_t preserve_order, best_effort, seen_problem; |
|
isc_boolean_t issigzero; |
|
|
|
diff --git a/lib/dns/rdataset.c b/lib/dns/rdataset.c |
|
index 026d771..483ddfb 100644 |
|
--- a/lib/dns/rdataset.c |
|
+++ b/lib/dns/rdataset.c |
|
@@ -336,6 +336,7 @@ towiresorted(dns_rdataset_t *rdataset, const dns_name_t *owner_name, |
|
*/ |
|
|
|
REQUIRE(DNS_RDATASET_VALID(rdataset)); |
|
+ REQUIRE(rdataset->methods != NULL); |
|
REQUIRE(countp != NULL); |
|
REQUIRE((order == NULL) == (order_arg == NULL)); |
|
REQUIRE(cctx != NULL && cctx->mctx != NULL); |
|
-- |
|
2.9.3 |
|
|
|
|