From: Evan Hunt Date: Thu, 27 Sep 2012 00:32:45 +0000 (-0700) Subject: fixed an exploitable hang bug X-Git-Tag: v9.8.4^0 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5dffd984bf533910e6a90f0621a15dab676d0ad2;p=thirdparty%2Fbind9.git fixed an exploitable hang bug 3383. [security] A certain combination of records in the RBT could cause named to hang while populating the additional section of a response. [RT #31090] --- diff --git a/CHANGES b/CHANGES index b670f798ea8..801f9918e5f 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,9 @@ --- 9.8.4 released --- +3383. [security] A certain combination of records in the RBT could + cause named to hang while populating the additional + section of a response. [RT #31090] + 3373. [bug] win32: open raw files in binary mode. [RT #30944] 3364. [security] Named could die on specially crafted record. diff --git a/bin/named/query.c b/bin/named/query.c index b717761feed..2bdaac820e4 100644 --- a/bin/named/query.c +++ b/bin/named/query.c @@ -1120,13 +1120,6 @@ query_isduplicate(ns_client_t *client, dns_name_t *name, mname = NULL; } - /* - * If the dns_name_t we're looking up is already in the message, - * we don't want to trigger the caller's name replacement logic. - */ - if (name == mname) - mname = NULL; - if (mnamep != NULL) *mnamep = mname; @@ -1325,6 +1318,7 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) { if (dns_rdataset_isassociated(rdataset) && !query_isduplicate(client, fname, type, &mname)) { if (mname != NULL) { + INSIST(mname != fname); query_releasename(client, &fname); fname = mname; } else @@ -1394,11 +1388,13 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) { #endif if (!query_isduplicate(client, fname, dns_rdatatype_a, &mname)) { - if (mname != NULL) { - query_releasename(client, &fname); - fname = mname; - } else - need_addname = ISC_TRUE; + if (mname != fname) { + if (mname != NULL) { + query_releasename(client, &fname); + fname = mname; + } else + need_addname = ISC_TRUE; + } ISC_LIST_APPEND(fname->list, rdataset, link); added_something = ISC_TRUE; if (sigrdataset != NULL && @@ -1451,11 +1447,13 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) { #endif if (!query_isduplicate(client, fname, dns_rdatatype_aaaa, &mname)) { - if (mname != NULL) { - query_releasename(client, &fname); - fname = mname; - } else - need_addname = ISC_TRUE; + if (mname != fname) { + if (mname != NULL) { + query_releasename(client, &fname); + fname = mname; + } else + need_addname = ISC_TRUE; + } ISC_LIST_APPEND(fname->list, rdataset, link); added_something = ISC_TRUE; if (sigrdataset != NULL && @@ -1978,22 +1976,24 @@ query_addadditional2(void *arg, dns_name_t *name, dns_rdatatype_t qtype) { crdataset->type == dns_rdatatype_aaaa) { if (!query_isduplicate(client, fname, crdataset->type, &mname)) { - if (mname != NULL) { - /* - * A different type of this name is - * already stored in the additional - * section. We'll reuse the name. - * Note that this should happen at most - * once. Otherwise, fname->link could - * leak below. - */ - INSIST(mname0 == NULL); - - query_releasename(client, &fname); - fname = mname; - mname0 = mname; - } else - need_addname = ISC_TRUE; + if (mname != fname) { + if (mname != NULL) { + /* + * A different type of this name is + * already stored in the additional + * section. We'll reuse the name. + * Note that this should happen at most + * once. Otherwise, fname->link could + * leak below. + */ + INSIST(mname0 == NULL); + + query_releasename(client, &fname); + fname = mname; + mname0 = mname; + } else + need_addname = ISC_TRUE; + } ISC_LIST_UNLINK(cfname.list, crdataset, link); ISC_LIST_APPEND(fname->list, crdataset, link); added_something = ISC_TRUE;