File CVE-2017-15120-4.0.7.patch of Package pdns-recursor.7583
Ported by: Adam Majer <amajer@suse.de>
Date: Mon Dec 11 16:31:28 CET 2017
Ported to pdns-recursor 4.0.5
Index: pdns-recursor-4.0.5/syncres.cc
===================================================================
--- pdns-recursor-4.0.5.orig/syncres.cc
+++ pdns-recursor-4.0.5/syncres.cc
@@ -530,9 +530,9 @@ vector<ComboAddress> SyncRes::getAddrs(c
if(!doResolve(qname, type, res,depth+1, beenthere) && !res.empty()) { // this consults cache, OR goes out
for(res_t::const_iterator i=res.begin(); i!= res.end(); ++i) {
if(i->d_type == QType::A || i->d_type == QType::AAAA) {
- if(auto rec = std::dynamic_pointer_cast<ARecordContent>(i->d_content))
+ if(auto rec = getRR<ARecordContent>(*i))
ret.push_back(rec->getCA(53));
- else if(auto aaaarec = std::dynamic_pointer_cast<AAAARecordContent>(i->d_content))
+ else if(auto aaaarec = getRR<AAAARecordContent>(*i))
ret.push_back(aaaarec->getCA(53));
done=true;
}
@@ -544,7 +544,7 @@ vector<ComboAddress> SyncRes::getAddrs(c
if(t_RC->get(d_now.tv_sec, qname, QType(QType::AAAA), &cset, d_requestor) > 0) {
for(auto k=cset.cbegin();k!=cset.cend();++k) {
if(k->d_ttl > (unsigned int)d_now.tv_sec ) {
- if (auto drc = std::dynamic_pointer_cast<AAAARecordContent>(k->d_content)) {
+ if (auto drc = getRR<AAAARecordContent>(*k)) {
ComboAddress ca=drc->getCA(53);
ret.push_back(ca);
}
@@ -621,8 +621,11 @@ void SyncRes::getBestNSFromCache(const D
GetBestNSAnswer answer;
answer.qname=qname;
answer.qtype=qtype.getCode();
- for(const auto& dr : bestns)
- answer.bestns.insert(make_pair(dr.d_name, getRR<NSRecordContent>(dr)->getNS()));
+ for(const auto& dr : bestns) {
+ if (auto nsContent = getRR<NSRecordContent>(dr)) {
+ answer.bestns.insert(make_pair(dr.d_name, nsContent->getNS()));
+ }
+ }
if(beenthere.count(answer)) {
brokeloop=true;
@@ -689,9 +692,11 @@ DNSName SyncRes::getBestNSNamesFromCache
for(auto k=bestns.cbegin() ; k != bestns.cend(); ++k) {
// The actual resolver code will not even look at the ComboAddress or bool
- nsset.insert({std::dynamic_pointer_cast<NSRecordContent>(k->d_content)->getNS(), {{}, false}});
- if(k==bestns.cbegin())
- subdomain=k->d_name;
+ if (auto nsContent = getRR<NSRecordContent>(*k)) {
+ nsset.insert({nsContent->getNS(), {{}, false}});
+ if(k==bestns.cbegin())
+ subdomain=k->d_name;
+ }
}
return subdomain;
}
@@ -716,6 +721,10 @@ bool SyncRes::doCNAMECacheCheck(const DN
if(t_RC->get(d_now.tv_sec, qname,QType(QType::CNAME), &cset, d_requestor, &signatures) > 0) {
for(auto j=cset.cbegin() ; j != cset.cend() ; ++j) {
+ if (j->d_class != QClass::IN) {
+ continue;
+ }
+
if(j->d_ttl>(unsigned int) d_now.tv_sec) {
LOG(prefix<<qname<<": Found cache CNAME hit for '"<< qname << "|CNAME" <<"' to '"<<j->d_content->getZoneRepresentation()<<"'"<<endl);
DNSRecord dr=*j;
@@ -735,7 +744,10 @@ bool SyncRes::doCNAMECacheCheck(const DN
if(!(qtype==QType(QType::CNAME))) { // perhaps they really wanted a CNAME!
set<GetBestNSAnswer>beenthere;
- res=doResolve(std::dynamic_pointer_cast<CNAMERecordContent>(j->d_content)->getTarget(), qtype, ret, depth+1, beenthere);
+ const auto cnameContent = getRR<CNAMERecordContent>(*j);
+ if (cnameContent) {
+ res=doResolve(cnameContent->getTarget(), qtype, ret, depth+1, beenthere);
+ }
}
else
res=0;
@@ -845,7 +857,13 @@ bool SyncRes::doCacheCheck(const DNSName
if(t_RC->get(d_now.tv_sec, sqname, sqt, &cset, d_requestor, d_doDNSSEC ? &signatures : 0) > 0) {
LOG(prefix<<sqname<<": Found cache hit for "<<sqt.getName()<<": ");
for(auto j=cset.cbegin() ; j != cset.cend() ; ++j) {
+
LOG(j->d_content->getZoneRepresentation());
+
+ if (j->d_class != QClass::IN) {
+ continue;
+ }
+
if(j->d_ttl>(unsigned int) d_now.tv_sec) {
DNSRecord dr=*j;
ttl = (dr.d_ttl-=d_now.tv_sec);
@@ -1247,6 +1265,9 @@ int SyncRes::doResolveAt(NsSet &nameserv
tcache_t tcache;
for(const auto& rec : lwr.d_records) {
+ if (rec.d_class != QClass::IN) {
+ continue;
+ }
if(rec.d_type == QType::RRSIG) {
auto rrsig = getRR<RRSIGRecordContent>(rec);
if (rrsig) {
@@ -1264,7 +1285,12 @@ int SyncRes::doResolveAt(NsSet &nameserv
}
LOG(prefix<<qname<<": accept answer '"<<rec.d_name<<"|"<<DNSRecordContent::NumberToType(rec.d_type)<<"|"<<rec.d_content->getZoneRepresentation()<<"' from '"<<auth<<"' nameservers? "<<(int)rec.d_place<<" ");
if(rec.d_type == QType::ANY) {
- LOG("NO! - we don't accept 'ANY' data"<<endl);
+ LOG("NO! - we don't accept 'ANY'-typed data"<<endl);
+ continue;
+ }
+
+ if(rec.d_class != QClass::IN) {
+ LOG("NO! - we don't accept records for any other class than 'IN'"<<endl);
continue;
}