From f05af77f32742b8e601d766e1f2fe6a480c7e735 Mon Sep 17 00:00:00 2001 From: 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