bind_Fix_for_CVE-2012-5166 Upstream-Status: Backport Reference:http://launchpadlibrarian.net/119212498/bind9_1%3A9.7.3.dfsOBg -1ubuntu2.6_1%3A9.7.3.dfsg-1ubuntu2.7.diff.gz ISC BIND 9.x before 9.7.6-P4, 9.8.x before 9.8.3-P4, 9.9.x before 9.9.1-P4, and 9.4-ESV and 9.6-ESV before 9.6-ESV-R7-P4 allows remote attackers to cause a denial of service (named daemon hang) via unspecified combinations of resource records. http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2012-5166 Signed-off-by: yanjun.zhu diff -urpN a/bin/named/query.c b/bin/named/query.c --- a/bin/named/query.c 2012-10-22 13:24:27.000000000 +0800 +++ b/bin/named/query.c 2012-10-22 13:17:04.000000000 +0800 @@ -1137,13 +1137,6 @@ query_isduplicate(ns_client_t *client, d 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; - *mnamep = mname; CTRACE("query_isduplicate: false: done"); @@ -1341,6 +1334,7 @@ query_addadditional(void *arg, dns_name_ if (dns_rdataset_isassociated(rdataset) && !query_isduplicate(client, fname, type, &mname)) { if (mname != NULL) { + INSIST(mname != fname); query_releasename(client, &fname); fname = mname; } else @@ -1401,11 +1395,13 @@ query_addadditional(void *arg, dns_name_ mname = NULL; 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 && @@ -1444,11 +1440,13 @@ query_addadditional(void *arg, dns_name_ mname = NULL; 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 && @@ -1960,22 +1958,24 @@ query_addadditional2(void *arg, dns_name 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;