--- Begin Message ---
Package: release.debian.org
Severity: normal
Tags: stretch
User: release.debian....@packages.debian.org
Usertags: pu
Dear Release Team,
I've prepared an update for pdns-recursor, which fixes some CVE issues.
As they are not critical bugs, security and me have agreed to do this via
a normal stable update, if that's okay with you too.
Sec bug: #913162
Thanks,
Chris
diff -Nru pdns-recursor-4.0.4/debian/changelog
pdns-recursor-4.0.4/debian/changelog
--- pdns-recursor-4.0.4/debian/changelog 2017-12-07 12:40:02.000000000
+0000
+++ pdns-recursor-4.0.4/debian/changelog 2018-11-10 16:05:33.000000000
+0000
@@ -1,3 +1,9 @@
+pdns-recursor (4.0.4-1+deb9u4) stretch-security; urgency=high
+
+ * Security upload for CVE-2018-10851 CVE-2018-14626 CVE-2018-14644 (Closes:
#913162).
+
+ -- Chris Hofstaedtler <z...@debian.org> Sat, 10 Nov 2018 16:05:33 +0000
+
pdns-recursor (4.0.4-1+deb9u3) stretch-security; urgency=high
* Security upload, including fix for CVE-2017-15120.
diff -Nru pdns-recursor-4.0.4/debian/patches/CVE-2018-10851-rec-4.0.8.patch
pdns-recursor-4.0.4/debian/patches/CVE-2018-10851-rec-4.0.8.patch
--- pdns-recursor-4.0.4/debian/patches/CVE-2018-10851-rec-4.0.8.patch
1970-01-01 00:00:00.000000000 +0000
+++ pdns-recursor-4.0.4/debian/patches/CVE-2018-10851-rec-4.0.8.patch
2018-11-10 16:05:33.000000000 +0000
@@ -0,0 +1,396 @@
+diff -ru pdns-recursor-4.0.8.orig/dnsparser.cc pdns-recursor-4.0.8/dnsparser.cc
+--- pdns-recursor-4.0.8.orig/dnsparser.cc 2017-12-11 11:38:52.000000000
+0100
++++ pdns-recursor-4.0.8/dnsparser.cc 2018-10-10 10:29:54.182145934 +0200
+@@ -121,54 +121,42 @@
+ return ret;
+ }
+
+-DNSRecordContent* DNSRecordContent::mastermake(const DNSRecord &dr,
+- PacketReader& pr)
++std::shared_ptr<DNSRecordContent> DNSRecordContent::mastermake(const
DNSRecord &dr,
++ PacketReader&
pr)
+ {
+ uint16_t searchclass = (dr.d_type == QType::OPT) ? 1 : dr.d_class; // class
is invalid for OPT
+
+ typemap_t::const_iterator i=getTypemap().find(make_pair(searchclass,
dr.d_type));
+ if(i==getTypemap().end() || !i->second) {
+- return new UnknownRecordContent(dr, pr);
++ return std::make_shared<UnknownRecordContent>(dr, pr);
+ }
+
+ return i->second(dr, pr);
+ }
+
+-DNSRecordContent* DNSRecordContent::mastermake(uint16_t qtype, uint16_t
qclass,
+- const string& content)
++std::shared_ptr<DNSRecordContent> DNSRecordContent::mastermake(uint16_t
qtype, uint16_t qclass,
++ const string&
content)
+ {
+ zmakermap_t::const_iterator i=getZmakermap().find(make_pair(qclass, qtype));
+ if(i==getZmakermap().end()) {
+- return new UnknownRecordContent(content);
++ return std::make_shared<UnknownRecordContent>(content);
+ }
+
+ return i->second(content);
+ }
+
+-std::unique_ptr<DNSRecordContent> DNSRecordContent::makeunique(uint16_t
qtype, uint16_t qclass,
+- const string& content)
+-{
+- zmakermap_t::const_iterator i=getZmakermap().find(make_pair(qclass, qtype));
+- if(i==getZmakermap().end()) {
+- return std::unique_ptr<DNSRecordContent>(new
UnknownRecordContent(content));
+- }
+-
+- return std::unique_ptr<DNSRecordContent>(i->second(content));
+-}
+-
+-
+-DNSRecordContent* DNSRecordContent::mastermake(const DNSRecord &dr,
PacketReader& pr, uint16_t oc) {
++std::shared_ptr<DNSRecordContent> DNSRecordContent::mastermake(const
DNSRecord &dr, PacketReader& pr, uint16_t oc) {
+ // For opcode UPDATE and where the DNSRecord is an answer record, we don't
care about content, because this is
+ // not used within the prerequisite section of RFC2136, so - we can simply
use unknownrecordcontent.
+ // For section 3.2.3, we do need content so we need to get it properly. But
only for the correct Qclasses.
+ if (oc == Opcode::Update && dr.d_place == DNSResourceRecord::ANSWER &&
dr.d_class != 1)
+- return new UnknownRecordContent(dr, pr);
++ return std::make_shared<UnknownRecordContent>(dr, pr);
+
+ uint16_t searchclass = (dr.d_type == QType::OPT) ? 1 : dr.d_class; // class
is invalid for OPT
+
+ typemap_t::const_iterator i=getTypemap().find(make_pair(searchclass,
dr.d_type));
+ if(i==getTypemap().end() || !i->second) {
+- return new UnknownRecordContent(dr, pr);
++ return std::make_shared<UnknownRecordContent>(dr, pr);
+ }
+
+ return i->second(dr, pr);
+diff -ru pdns-recursor-4.0.8.orig/dnsparser.hh pdns-recursor-4.0.8/dnsparser.hh
+--- pdns-recursor-4.0.8.orig/dnsparser.hh 2017-12-11 11:38:52.000000000
+0100
++++ pdns-recursor-4.0.8/dnsparser.hh 2018-10-10 10:29:54.182145934 +0200
+@@ -166,10 +166,9 @@
+ class DNSRecordContent
+ {
+ public:
+- static DNSRecordContent* mastermake(const DNSRecord &dr, PacketReader& pr);
+- static DNSRecordContent* mastermake(const DNSRecord &dr, PacketReader& pr,
uint16_t opcode);
+- static DNSRecordContent* mastermake(uint16_t qtype, uint16_t qclass, const
string& zone);
+- static std::unique_ptr<DNSRecordContent> makeunique(uint16_t qtype,
uint16_t qclass, const string& content);
++ static std::shared_ptr<DNSRecordContent> mastermake(const DNSRecord &dr,
PacketReader& pr);
++ static std::shared_ptr<DNSRecordContent> mastermake(const DNSRecord &dr,
PacketReader& pr, uint16_t opcode);
++ static std::shared_ptr<DNSRecordContent> mastermake(uint16_t qtype,
uint16_t qclass, const string& zone);
+
+ virtual std::string getZoneRepresentation(bool noDot=false) const = 0;
+ virtual ~DNSRecordContent() {}
+@@ -198,8 +197,8 @@
+
+ void doRecordCheck(const struct DNSRecord&){}
+
+- typedef DNSRecordContent* makerfunc_t(const struct DNSRecord& dr,
PacketReader& pr);
+- typedef DNSRecordContent* zmakerfunc_t(const string& str);
++ typedef std::shared_ptr<DNSRecordContent> makerfunc_t(const struct
DNSRecord& dr, PacketReader& pr);
++ typedef std::shared_ptr<DNSRecordContent> zmakerfunc_t(const string& str);
+
+ static void regist(uint16_t cl, uint16_t ty, makerfunc_t* f, zmakerfunc_t*
z, const char* name)
+ {
+diff -ru pdns-recursor-4.0.8.orig/dnsrecords.cc
pdns-recursor-4.0.8/dnsrecords.cc
+--- pdns-recursor-4.0.8.orig/dnsrecords.cc 2017-12-11 11:38:52.000000000
+0100
++++ pdns-recursor-4.0.8/dnsrecords.cc 2018-10-10 10:29:54.182145934 +0200
+@@ -386,19 +386,19 @@
+ {
+ regist(1, QType::EUI48, &make, &make, "EUI48");
+ }
+-DNSRecordContent* EUI48RecordContent::make(const DNSRecord &dr, PacketReader&
pr)
++std::shared_ptr<DNSRecordContent> EUI48RecordContent::make(const DNSRecord
&dr, PacketReader& pr)
+ {
+ if(dr.d_clen!=6)
+ throw MOADNSException("Wrong size for EUI48 record");
+
+- EUI48RecordContent* ret=new EUI48RecordContent();
++ auto ret=std::make_shared<EUI48RecordContent>();
+ pr.copyRecord((uint8_t*) &ret->d_eui48, 6);
+ return ret;
+ }
+-DNSRecordContent* EUI48RecordContent::make(const string& zone)
++std::shared_ptr<DNSRecordContent> EUI48RecordContent::make(const string& zone)
+ {
+ // try to parse
+- EUI48RecordContent *ret=new EUI48RecordContent();
++ auto ret=std::make_shared<EUI48RecordContent>();
+ // format is 6 hex bytes and dashes
+ if (sscanf(zone.c_str(), "%2hhx-%2hhx-%2hhx-%2hhx-%2hhx-%2hhx",
+ ret->d_eui48, ret->d_eui48+1, ret->d_eui48+2,
+@@ -429,19 +429,19 @@
+ {
+ regist(1, QType::EUI64, &make, &make, "EUI64");
+ }
+-DNSRecordContent* EUI64RecordContent::make(const DNSRecord &dr, PacketReader&
pr)
++std::shared_ptr<DNSRecordContent> EUI64RecordContent::make(const DNSRecord
&dr, PacketReader& pr)
+ {
+ if(dr.d_clen!=8)
+ throw MOADNSException("Wrong size for EUI64 record");
+
+- EUI64RecordContent* ret=new EUI64RecordContent();
++ auto ret=std::make_shared<EUI64RecordContent>();
+ pr.copyRecord((uint8_t*) &ret->d_eui64, 8);
+ return ret;
+ }
+-DNSRecordContent* EUI64RecordContent::make(const string& zone)
++std::shared_ptr<DNSRecordContent> EUI64RecordContent::make(const string& zone)
+ {
+ // try to parse
+- EUI64RecordContent *ret=new EUI64RecordContent();
++ auto ret=std::make_shared<EUI64RecordContent>();
+ // format is 8 hex bytes and dashes
+ if (sscanf(zone.c_str(),
"%2hhx-%2hhx-%2hhx-%2hhx-%2hhx-%2hhx-%2hhx-%2hhx",
+ ret->d_eui64, ret->d_eui64+1, ret->d_eui64+2,
+diff -ru pdns-recursor-4.0.8.orig/dnsrecords.hh
pdns-recursor-4.0.8/dnsrecords.hh
+--- pdns-recursor-4.0.8.orig/dnsrecords.hh 2017-12-11 11:38:52.000000000
+0100
++++ pdns-recursor-4.0.8/dnsrecords.hh 2018-10-10 10:29:54.182145934 +0200
+@@ -33,8 +33,8 @@
+ RNAME##RecordContent(const string& zoneData);
\
+ static void report(void);
\
+ static void unreport(void);
\
+- static DNSRecordContent* make(const DNSRecord &dr, PacketReader& pr);
\
+- static DNSRecordContent* make(const string& zonedata);
\
++ static std::shared_ptr<DNSRecordContent> make(const DNSRecord &dr,
PacketReader& pr); \
++ static std::shared_ptr<DNSRecordContent> make(const string& zonedata);
\
+ string getZoneRepresentation(bool noDot=false) const override;
\
+ void toPacket(DNSPacketWriter& pw) override;
\
+ uint16_t getType() const override { return QType::RNAME; }
\
+@@ -467,8 +467,8 @@
+ {}
+ NSECRecordContent(const string& content, const string& zone="");
//FIXME400: DNSName& zone?
+
+- static DNSRecordContent* make(const DNSRecord &dr, PacketReader& pr);
+- static DNSRecordContent* make(const string& content);
++ static std::shared_ptr<DNSRecordContent> make(const DNSRecord &dr,
PacketReader& pr);
++ static std::shared_ptr<DNSRecordContent> make(const string& content);
+ string getZoneRepresentation(bool noDot=false) const override;
+ void toPacket(DNSPacketWriter& pw) override;
+ uint16_t getType() const override
+@@ -488,8 +488,8 @@
+ {}
+ NSEC3RecordContent(const string& content, const string& zone="");
//FIXME400: DNSName& zone?
+
+- static DNSRecordContent* make(const DNSRecord &dr, PacketReader& pr);
+- static DNSRecordContent* make(const string& content);
++ static std::shared_ptr<DNSRecordContent> make(const DNSRecord &dr,
PacketReader& pr);
++ static std::shared_ptr<DNSRecordContent> make(const string& content);
+ string getZoneRepresentation(bool noDot=false) const override;
+ void toPacket(DNSPacketWriter& pw) override;
+
+@@ -517,8 +517,8 @@
+ {}
+ NSEC3PARAMRecordContent(const string& content, const string& zone=""); //
FIXME400: DNSName& zone?
+
+- static DNSRecordContent* make(const DNSRecord &dr, PacketReader& pr);
+- static DNSRecordContent* make(const string& content);
++ static std::shared_ptr<DNSRecordContent> make(const DNSRecord &dr,
PacketReader& pr);
++ static std::shared_ptr<DNSRecordContent> make(const string& content);
+ string getZoneRepresentation(bool noDot=false) const override;
+ void toPacket(DNSPacketWriter& pw) override;
+
+@@ -542,8 +542,8 @@
+ {}
+ LOCRecordContent(const string& content, const string& zone="");
+
+- static DNSRecordContent* make(const DNSRecord &dr, PacketReader& pr);
+- static DNSRecordContent* make(const string& content);
++ static std::shared_ptr<DNSRecordContent> make(const DNSRecord &dr,
PacketReader& pr);
++ static std::shared_ptr<DNSRecordContent> make(const string& content);
+ string getZoneRepresentation(bool noDot=false) const override;
+ void toPacket(DNSPacketWriter& pw) override;
+
+@@ -566,8 +566,8 @@
+ {}
+ WKSRecordContent(const string& content, const string& zone=""); //
FIXME400: DNSName& zone?
+
+- static DNSRecordContent* make(const DNSRecord &dr, PacketReader& pr);
+- static DNSRecordContent* make(const string& content);
++ static std::shared_ptr<DNSRecordContent> make(const DNSRecord &dr,
PacketReader& pr);
++ static std::shared_ptr<DNSRecordContent> make(const string& content);
+ string getZoneRepresentation(bool noDot=false) const override;
+ void toPacket(DNSPacketWriter& pw) override;
+
+@@ -581,8 +581,8 @@
+ public:
+ EUI48RecordContent() {};
+ static void report(void);
+- static DNSRecordContent* make(const DNSRecord &dr, PacketReader& pr);
+- static DNSRecordContent* make(const string& zone); // FIXME400: DNSName&
zone?
++ static std::shared_ptr<DNSRecordContent> make(const DNSRecord &dr,
PacketReader& pr);
++ static std::shared_ptr<DNSRecordContent> make(const string& zone); //
FIXME400: DNSName& zone?
+ string getZoneRepresentation(bool noDot=false) const override;
+ void toPacket(DNSPacketWriter& pw) override;
+ uint16_t getType() const override { return QType::EUI48; }
+@@ -596,8 +596,8 @@
+ public:
+ EUI64RecordContent() {};
+ static void report(void);
+- static DNSRecordContent* make(const DNSRecord &dr, PacketReader& pr);
+- static DNSRecordContent* make(const string& zone); // FIXME400: DNSName&
zone?
++ static std::shared_ptr<DNSRecordContent> make(const DNSRecord &dr,
PacketReader& pr);
++ static std::shared_ptr<DNSRecordContent> make(const string& zone); //
FIXME400: DNSName& zone?
+ string getZoneRepresentation(bool noDot=false) const override;
+ void toPacket(DNSPacketWriter& pw) override;
+ uint16_t getType() const override { return QType::EUI64; }
+@@ -644,9 +644,9 @@
+ };
+
+ #define boilerplate(RNAME, RTYPE)
\
+-RNAME##RecordContent::DNSRecordContent* RNAME##RecordContent::make(const
DNSRecord& dr, PacketReader& pr) \
++std::shared_ptr<RNAME##RecordContent::DNSRecordContent>
RNAME##RecordContent::make(const DNSRecord& dr, PacketReader& pr) \
+ {
\
+- return new RNAME##RecordContent(dr, pr);
\
++ return std::make_shared<RNAME##RecordContent>(dr, pr);
\
+ }
\
+
\
+ RNAME##RecordContent::RNAME##RecordContent(const DNSRecord& dr, PacketReader&
pr) \
+@@ -655,9 +655,9 @@
+ xfrPacket(pr);
\
+ }
\
+
\
+-RNAME##RecordContent::DNSRecordContent* RNAME##RecordContent::make(const
string& zonedata) \
++std::shared_ptr<RNAME##RecordContent::DNSRecordContent>
RNAME##RecordContent::make(const string& zonedata) \
+ {
\
+- return new RNAME##RecordContent(zonedata);
\
++ return std::make_shared<RNAME##RecordContent>(zonedata);
\
+ }
\
+
\
+ void RNAME##RecordContent::toPacket(DNSPacketWriter& pw)
\
+diff -ru pdns-recursor-4.0.8.orig/nsecrecords.cc
pdns-recursor-4.0.8/nsecrecords.cc
+--- pdns-recursor-4.0.8.orig/nsecrecords.cc 2017-12-11 11:38:52.000000000
+0100
++++ pdns-recursor-4.0.8/nsecrecords.cc 2018-10-10 10:29:54.182145934 +0200
+@@ -29,9 +29,9 @@
+ regist(1, 47, &make, &make, "NSEC");
+ }
+
+-DNSRecordContent* NSECRecordContent::make(const string& content)
++std::shared_ptr<DNSRecordContent> NSECRecordContent::make(const string&
content)
+ {
+- return new NSECRecordContent(content);
++ return std::make_shared<NSECRecordContent>(content);
+ }
+
+ NSECRecordContent::NSECRecordContent(const string& content, const string&
zone)
+@@ -81,9 +81,9 @@
+ pw.xfrBlob(tmp);
+ }
+
+-NSECRecordContent::DNSRecordContent* NSECRecordContent::make(const DNSRecord
&dr, PacketReader& pr)
++std::shared_ptr<NSECRecordContent::DNSRecordContent>
NSECRecordContent::make(const DNSRecord &dr, PacketReader& pr)
+ {
+- NSECRecordContent* ret=new NSECRecordContent();
++ auto ret=std::make_shared<NSECRecordContent>();
+ pr.xfrName(ret->d_next);
+ string bitmap;
+ pr.xfrBlob(bitmap);
+@@ -136,9 +136,9 @@
+ regist(1, 50, &make, &make, "NSEC3");
+ }
+
+-DNSRecordContent* NSEC3RecordContent::make(const string& content)
++std::shared_ptr<DNSRecordContent> NSEC3RecordContent::make(const string&
content)
+ {
+- return new NSEC3RecordContent(content);
++ return std::make_shared<NSEC3RecordContent>(content);
+ }
+
+ NSEC3RecordContent::NSEC3RecordContent(const string& content, const string&
zone)
+@@ -203,9 +203,9 @@
+ }
+ }
+
+-NSEC3RecordContent::DNSRecordContent* NSEC3RecordContent::make(const
DNSRecord &dr, PacketReader& pr)
++std::shared_ptr<NSEC3RecordContent::DNSRecordContent>
NSEC3RecordContent::make(const DNSRecord &dr, PacketReader& pr)
+ {
+- NSEC3RecordContent* ret=new NSEC3RecordContent();
++ auto ret=std::make_shared<NSEC3RecordContent>();
+ pr.xfr8BitInt(ret->d_algorithm);
+ pr.xfr8BitInt(ret->d_flags);
+ pr.xfr16BitInt(ret->d_iterations);
+@@ -273,9 +273,9 @@
+ regist(254, 51, &make, &make, "NSEC3PARAM");
+ }
+
+-DNSRecordContent* NSEC3PARAMRecordContent::make(const string& content)
++std::shared_ptr<DNSRecordContent> NSEC3PARAMRecordContent::make(const string&
content)
+ {
+- return new NSEC3PARAMRecordContent(content);
++ return std::make_shared<NSEC3PARAMRecordContent>(content);
+ }
+
+ NSEC3PARAMRecordContent::NSEC3PARAMRecordContent(const string& content, const
string& zone)
+@@ -297,9 +297,9 @@
+ pw.xfrBlob(d_salt);
+ }
+
+-NSEC3PARAMRecordContent::DNSRecordContent*
NSEC3PARAMRecordContent::make(const DNSRecord &dr, PacketReader& pr)
++std::shared_ptr<NSEC3PARAMRecordContent::DNSRecordContent>
NSEC3PARAMRecordContent::make(const DNSRecord &dr, PacketReader& pr)
+ {
+- NSEC3PARAMRecordContent* ret=new NSEC3PARAMRecordContent();
++ auto ret=std::make_shared<NSEC3PARAMRecordContent>();
+ pr.xfr8BitInt(ret->d_algorithm);
+ pr.xfr8BitInt(ret->d_flags);
+ pr.xfr16BitInt(ret->d_iterations);
+diff -ru pdns-recursor-4.0.8.orig/rec-lua-conf.cc
pdns-recursor-4.0.8/rec-lua-conf.cc
+--- pdns-recursor-4.0.8.orig/rec-lua-conf.cc 2017-12-11 11:38:52.000000000
+0100
++++ pdns-recursor-4.0.8/rec-lua-conf.cc 2018-10-10 10:29:54.182145934
+0200
+@@ -35,7 +35,7 @@
+ LuaConfigItems::LuaConfigItems()
+ {
+ for (const auto &dsRecord : rootDSs) {
+- auto
ds=unique_ptr<DSRecordContent>(dynamic_cast<DSRecordContent*>(DSRecordContent::make(dsRecord)));
++ auto
ds=std::dynamic_pointer_cast<DSRecordContent>(DSRecordContent::make(dsRecord));
+ dsAnchors[DNSName(".")].insert(*ds);
+ }
+ }
+@@ -240,7 +240,7 @@
+
+ Lua.writeFunction("addDS", [&lci](const std::string& who, const
std::string& what) {
+ DNSName zone(who);
+- auto ds =
unique_ptr<DSRecordContent>(dynamic_cast<DSRecordContent*>(DSRecordContent::make(what)));
++ auto
ds=std::dynamic_pointer_cast<DSRecordContent>(DSRecordContent::make(what));
+ lci.dsAnchors[zone].insert(*ds);
+ });
+
+diff -ru pdns-recursor-4.0.8.orig/rec_channel_rec.cc
pdns-recursor-4.0.8/rec_channel_rec.cc
+--- pdns-recursor-4.0.8.orig/rec_channel_rec.cc 2017-12-11
11:38:52.000000000 +0100
++++ pdns-recursor-4.0.8/rec_channel_rec.cc 2018-10-10 10:29:54.182145934
+0200
+@@ -490,7 +490,7 @@
+ try {
+ L<<Logger::Warning<<"Adding Trust Anchor for "<<who<<" with data
'"<<what<<"', requested via control channel";
+ g_luaconfs.modify([who, what](LuaConfigItems& lci) {
+- auto ds =
unique_ptr<DSRecordContent>(dynamic_cast<DSRecordContent*>(DSRecordContent::make(what)));
++ auto
ds=std::dynamic_pointer_cast<DSRecordContent>(DSRecordContent::make(what));
+ lci.dsAnchors[who].insert(*ds);
+ });
+ broadcastAccFunction<uint64_t>(boost::bind(pleaseWipePacketCache, who,
true));
+diff -ru pdns-recursor-4.0.8.orig/sillyrecords.cc
pdns-recursor-4.0.8/sillyrecords.cc
+--- pdns-recursor-4.0.8.orig/sillyrecords.cc 2017-12-11 11:38:52.000000000
+0100
++++ pdns-recursor-4.0.8/sillyrecords.cc 2018-10-10 10:29:54.182145934
+0200
+@@ -159,9 +159,9 @@
+ regist(254, QType::LOC, &make, &make, "LOC");
+ }
+
+-DNSRecordContent* LOCRecordContent::make(const string& content)
++std::shared_ptr<DNSRecordContent> LOCRecordContent::make(const string&
content)
+ {
+- return new LOCRecordContent(content);
++ return std::make_shared<LOCRecordContent>(content);
+ }
+
+
+@@ -177,9 +177,9 @@
+ pw.xfr32BitInt(d_altitude);
+ }
+
+-LOCRecordContent::DNSRecordContent* LOCRecordContent::make(const DNSRecord
&dr, PacketReader& pr)
++std::shared_ptr<LOCRecordContent::DNSRecordContent>
LOCRecordContent::make(const DNSRecord &dr, PacketReader& pr)
+ {
+- LOCRecordContent* ret=new LOCRecordContent();
++ auto ret=std::make_shared<LOCRecordContent>();
+ pr.xfr8BitInt(ret->d_version);
+ pr.xfr8BitInt(ret->d_size);
+ pr.xfr8BitInt(ret->d_horizpre);
diff -Nru pdns-recursor-4.0.4/debian/patches/CVE-2018-14626-rec-4.0.8.patch
pdns-recursor-4.0.4/debian/patches/CVE-2018-14626-rec-4.0.8.patch
--- pdns-recursor-4.0.4/debian/patches/CVE-2018-14626-rec-4.0.8.patch
1970-01-01 00:00:00.000000000 +0000
+++ pdns-recursor-4.0.4/debian/patches/CVE-2018-14626-rec-4.0.8.patch
2018-11-10 16:05:33.000000000 +0000
@@ -0,0 +1,238 @@
+diff -ru pdns-recursor-4.0.8.orig/pdns_recursor.cc
pdns-recursor-4.0.8/pdns_recursor.cc
+--- pdns-recursor-4.0.8.orig/pdns_recursor.cc 2017-12-11 11:38:52.000000000
+0100
++++ pdns-recursor-4.0.8/pdns_recursor.cc 2018-10-09 17:14:58.052450425
+0200
+@@ -1134,7 +1134,7 @@
+ if(sendmsg(dc->d_socket, &msgh, 0) < 0 && g_logCommonErrors)
+ L<<Logger::Warning<<"Sending UDP reply to client
"<<dc->d_remote.toStringWithPort()<<" failed with: "<<strerror(errno)<<endl;
+ if(!SyncRes::s_nopacketcache && !variableAnswer && !sr.wasVariable() ) {
+- t_packetCache->insertResponsePacket(dc->d_tag, dc->d_mdp.d_qname,
dc->d_mdp.d_qtype, dc->d_query,
++ t_packetCache->insertResponsePacket(dc->d_tag, dc->d_mdp.d_qname,
dc->d_mdp.d_qtype, dc->d_mdp.d_qclass, dc->d_query,
+ string((const
char*)&*packet.begin(), packet.size()),
+ g_now.tv_sec,
+ pw.getHeader()->rcode ==
RCode::ServFail ? SyncRes::s_packetcacheservfailttl :
+diff -ru pdns-recursor-4.0.8.orig/recpacketcache.cc
pdns-recursor-4.0.8/recpacketcache.cc
+--- pdns-recursor-4.0.8.orig/recpacketcache.cc 2017-12-11 11:38:52.000000000
+0100
++++ pdns-recursor-4.0.8/recpacketcache.cc 2018-10-09 17:08:20.176479437
+0200
+@@ -42,17 +42,59 @@
+ return count;
+ }
+
++static bool queryHeaderMatches(const std::string& cachedQuery, const
std::string& query)
++{
++ if (cachedQuery.size() != query.size()) {
++ return false;
++ }
++
++ return (cachedQuery.compare(/* skip the ID */ 2, sizeof(dnsheader) - 2,
query, 2, sizeof(dnsheader) - 2) == 0);
++}
++
++bool RecursorPacketCache::queryMatches(const std::string& cachedQuery, const
std::string& query, const DNSName& qname, uint16_t ecsBegin, uint16_t ecsEnd)
++{
++ if (!queryHeaderMatches(cachedQuery, query)) {
++ return false;
++ }
++
++ size_t pos = sizeof(dnsheader) + qname.wirelength();
++
++ if (ecsBegin != 0 && ecsBegin >= pos && ecsEnd > ecsBegin) {
++ if (cachedQuery.compare(pos, ecsBegin - pos, query, pos, ecsBegin - pos)
!= 0) {
++ return false;
++ }
++
++ if (cachedQuery.compare(ecsEnd, cachedQuery.size() - ecsEnd, query,
ecsEnd, query.size() - ecsEnd) != 0) {
++ return false;
++ }
++ }
++ else {
++ if (cachedQuery.compare(pos, cachedQuery.size() - pos, query, pos,
query.size() - pos) != 0) {
++ return false;
++ }
++ }
++
++ return true;
++}
++
+ // one day this function could be really fast by doing only a case
insensitive compare
+-static bool qrMatch(const std::string& query, const std::string& response)
++bool RecursorPacketCache::qrMatch(const
packetCache_t::index<HashTag>::type::iterator& iter, const std::string&
queryPacket, uint16_t ecsBegin, uint16_t ecsEnd)
+ {
+- uint16_t rqtype, rqclass, qqtype, qqclass;
+- DNSName queryname(query.c_str(), query.length(), sizeof(dnsheader), false,
&qqtype, &qqclass, 0);
+- DNSName respname(response.c_str(), response.length(), sizeof(dnsheader),
false, &rqtype, &rqclass, 0);
+- // this ignores checking on the EDNS subnet flags!
+- return queryname==respname && rqtype == qqtype && rqclass == qqclass;
++ uint16_t qqtype, qqclass;
++ DNSName queryname(queryPacket.c_str(), queryPacket.length(),
sizeof(dnsheader), false, &qqtype, &qqclass, 0);
++ // this ignores checking on the EDNS subnet flags!
++ if (qqtype != iter->d_type || qqclass != iter->d_class || queryname !=
iter->d_name) {
++ return false;
++ }
++
++ if (iter->d_ecsBegin != ecsBegin || iter->d_ecsEnd != ecsEnd) {
++ return false;
++ }
++
++ return queryMatches(iter->d_query, queryPacket, queryname, ecsBegin,
ecsEnd);
+ }
+
+-uint32_t RecursorPacketCache::canHashPacket(const std::string& origPacket)
++uint32_t RecursorPacketCache::canHashPacket(const std::string& origPacket,
uint16_t* ecsBegin, uint16_t* ecsEnd)
+ {
+ // return 42; // should still work if you do this!
+ uint32_t ret=0;
+@@ -68,6 +110,10 @@
+ struct dnsheader* dh = (struct dnsheader*)origPacket.c_str();
+ const char* skipBegin = p;
+ const char* skipEnd = p;
++ if (ecsBegin != nullptr && ecsEnd != nullptr) {
++ *ecsBegin = 0;
++ *ecsEnd = 0;
++ }
+ /* we need at least 1 (final empty label) + 2 (QTYPE) + 2 (QCLASS)
+ + OPT root label (1), type (2), class (2) and ttl (4)
+ + the OPT RR rdlen (2)
+@@ -82,6 +128,10 @@
+ if (res == 0) {
+ skipBegin = optionBegin;
+ skipEnd = optionBegin + optionLen;
++ if (ecsBegin != nullptr && ecsEnd != nullptr) {
++ *ecsBegin = optionBegin - origPacket.c_str();
++ *ecsEnd = *ecsBegin + optionLen;
++ }
+ }
+ }
+ if (skipBegin > p) {
+@@ -96,15 +146,11 @@
+ }
+
+ bool RecursorPacketCache::getResponsePacket(unsigned int tag, const
std::string& queryPacket, time_t now,
+- std::string* responsePacket,
uint32_t* age)
+-{
+- return getResponsePacket(tag, queryPacket, now, responsePacket, age,
nullptr);
+-}
+-
+-bool RecursorPacketCache::getResponsePacket(unsigned int tag, const
std::string& queryPacket, time_t now,
+ std::string* responsePacket,
uint32_t* age, RecProtoBufMessage* protobufMessage)
+ {
+- uint32_t h = canHashPacket(queryPacket);
++ uint16_t ecsBegin = 0;
++ uint16_t ecsEnd = 0;
++ uint32_t h = canHashPacket(queryPacket, &ecsBegin, &ecsEnd);
+ auto& idx = d_packetCache.get<HashTag>();
+ auto range = idx.equal_range(tie(tag,h));
+
+@@ -115,8 +161,9 @@
+
+ for(auto iter = range.first ; iter != range.second ; ++ iter) {
+ // the possibility is VERY real that we get hits that are not right -
birthday paradox
+- if(!qrMatch(queryPacket, iter->d_packet))
++ if(!qrMatch(iter, queryPacket, ecsBegin, ecsEnd)) {
+ continue;
++ }
+ if((uint32_t)now < iter->d_ttd) { // it is right, it is fresh!
+ *age = now - iter->d_creation;
+ *responsePacket = iter->d_packet;
+@@ -153,27 +200,28 @@
+ }
+
+
+-void RecursorPacketCache::insertResponsePacket(unsigned int tag, const
DNSName& qname, uint16_t qtype, const std::string& queryPacket, const
std::string& responsePacket, time_t now, uint32_t ttl)
++void RecursorPacketCache::insertResponsePacket(unsigned int tag, const
DNSName& qname, uint16_t qtype, uint16_t qclass, const std::string&
queryPacket, const std::string& responsePacket, time_t now, uint32_t ttl, const
RecProtoBufMessage* protobufMessage)
+ {
+- insertResponsePacket(tag, qname, qtype, queryPacket, responsePacket, now,
ttl, nullptr);
+-}
+-
+-void RecursorPacketCache::insertResponsePacket(unsigned int tag, const
DNSName& qname, uint16_t qtype, const std::string& queryPacket, const
std::string& responsePacket, time_t now, uint32_t ttl, const
RecProtoBufMessage* protobufMessage)
+-{
+- auto qhash = canHashPacket(queryPacket);
++ uint16_t ecsBegin = 0;
++ uint16_t ecsEnd = 0;
++ auto qhash = canHashPacket(queryPacket, &ecsBegin, &ecsEnd);
+ auto& idx = d_packetCache.get<HashTag>();
+ auto range = idx.equal_range(tie(tag,qhash));
+ auto iter = range.first;
+
+ for( ; iter != range.second ; ++iter) {
+- if(iter->d_type != qtype)
++ if(iter->d_type != qtype || iter->d_class != qclass) {
+ continue;
++ }
+ // this only happens on insert which is relatively rare and does not need
to be super fast
+ DNSName respname(iter->d_packet.c_str(), iter->d_packet.length(),
sizeof(dnsheader), false, 0, 0, 0);
+ if(qname != respname)
+ continue;
+ moveCacheItemToBack(d_packetCache, iter);
+ iter->d_packet = responsePacket;
++ iter->d_query = queryPacket;
++ iter->d_ecsBegin = ecsBegin;
++ iter->d_ecsEnd = ecsEnd;
+ iter->d_ttd = now + ttl;
+ iter->d_creation = now;
+ #ifdef HAVE_PROTOBUF
+@@ -188,9 +236,13 @@
+ if(iter == range.second) { // nothing to refresh
+ struct Entry e;
+ e.d_packet = responsePacket;
++ e.d_query = queryPacket;
+ e.d_name = qname;
+ e.d_qhash = qhash;
+ e.d_type = qtype;
++ e.d_class = qclass;
++ e.d_ecsBegin = ecsBegin;
++ e.d_ecsEnd = ecsEnd;
+ e.d_ttd = now+ttl;
+ e.d_creation = now;
+ e.d_tag = tag;
+diff -ru pdns-recursor-4.0.8.orig/recpacketcache.hh
pdns-recursor-4.0.8/recpacketcache.hh
+--- pdns-recursor-4.0.8.orig/recpacketcache.hh 2017-12-11 11:38:52.000000000
+0100
++++ pdns-recursor-4.0.8/recpacketcache.hh 2018-10-09 17:14:58.052450425
+0200
+@@ -50,10 +50,8 @@
+ {
+ public:
+ RecursorPacketCache();
+- bool getResponsePacket(unsigned int tag, const std::string& queryPacket,
time_t now, std::string* responsePacket, uint32_t* age);
+- void insertResponsePacket(unsigned int tag, const DNSName& qname, uint16_t
qtype, const std::string& queryPacket, const std::string& responsePacket,
time_t now, uint32_t ttd);
+ bool getResponsePacket(unsigned int tag, const std::string& queryPacket,
time_t now, std::string* responsePacket, uint32_t* age, RecProtoBufMessage*
protobufMessage);
+- void insertResponsePacket(unsigned int tag, const DNSName& qname, uint16_t
qtype, const std::string& queryPacket, const std::string& responsePacket,
time_t now, uint32_t ttd, const RecProtoBufMessage* protobufMessage);
++ void insertResponsePacket(unsigned int tag, const DNSName& qname, uint16_t
qtype, uint16_t qclass, const std::string& queryPacket, const std::string&
responsePacket, time_t now, uint32_t ttd, const RecProtoBufMessage*
protobufMessage);
+ void doPruneTo(unsigned int maxSize=250000);
+ uint64_t doDump(int fd);
+ int doWipePacketCache(const DNSName& name, uint16_t qtype=0xffff, bool
subtree=false);
+@@ -72,12 +70,16 @@
+ mutable uint32_t d_creation; // so we can 'age' our packets
+ DNSName d_name;
+ uint16_t d_type;
++ uint16_t d_class;
+ mutable std::string d_packet; // "I know what I am doing"
++ mutable std::string d_query;
+ #ifdef HAVE_PROTOBUF
+ mutable RecProtoBufMessage d_protobufMessage;
+ #endif
+ uint32_t d_qhash;
+ uint32_t d_tag;
++ mutable uint16_t d_ecsBegin;
++ mutable uint16_t d_ecsEnd;
+ inline bool operator<(const struct Entry& rhs) const;
+
+ uint32_t getTTD() const
+@@ -85,7 +87,7 @@
+ return d_ttd;
+ }
+ };
+- uint32_t canHashPacket(const std::string& origPacket);
++
+ typedef multi_index_container<
+ Entry,
+ indexed_by <
+@@ -96,6 +98,11 @@
+ > packetCache_t;
+
+ packetCache_t d_packetCache;
++
++public:
++ static bool queryMatches(const std::string& cachedQuery, const std::string&
query, const DNSName& qname, uint16_t ecsBegin, uint16_t ecsEnd);
++ static bool qrMatch(const packetCache_t::index<HashTag>::type::iterator&
iter, const std::string& queryPacket, uint16_t ecsBegin, uint16_t ecsEnd);
++ static uint32_t canHashPacket(const std::string& origPacket, uint16_t*
ecsBegin, uint16_t* ecsEnd);
+ };
+
+ #endif
diff -Nru pdns-recursor-4.0.4/debian/patches/CVE-2018-14644-rec-4.0.4.patch
pdns-recursor-4.0.4/debian/patches/CVE-2018-14644-rec-4.0.4.patch
--- pdns-recursor-4.0.4/debian/patches/CVE-2018-14644-rec-4.0.4.patch
1970-01-01 00:00:00.000000000 +0000
+++ pdns-recursor-4.0.4/debian/patches/CVE-2018-14644-rec-4.0.4.patch
2018-11-10 16:05:33.000000000 +0000
@@ -0,0 +1,25 @@
+From a61af1fcec7f9c5fb94a8cdba7dc0ac1f3e4791c Mon Sep 17 00:00:00 2001
+From: Chris Hofstaedtler <chris.hofstaedt...@deduktiva.com>
+Date: Sat, 10 Nov 2018 17:02:30 +0100
+Subject: [PATCH] rec: Refuse queries for all meta-types
+
+Backport be44629dd2ef0f6805826fb6794f7a996c34aab4 from 4.1.x to 4.0.x
+---
+ syncres.cc | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/syncres.cc b/syncres.cc
+index f121cfac2d..f8b39ee8fb 100644
+--- a/syncres.cc
++++ b/syncres.cc
+@@ -128,7 +128,9 @@ int SyncRes::beginResolve(const DNSName &qname, const
QType &qtype, uint16_t qcl
+ d_wasVariable=false;
+ d_wasOutOfBand=false;
+
+- if( (qtype.getCode() == QType::AXFR))
++ auto qtypeCode = qtype.getCode();
++ /* rfc6895 section 3.1 */
++ if ((qtypeCode >= 128 && qtypeCode <= 254) || qtypeCode == QType::RRSIG ||
qtypeCode == QType::NSEC3 || qtypeCode == QType::OPT || qtypeCode == 65535)
+ return -1;
+
+ static const DNSName arpa("1.0.0.127.in-addr.arpa."),
localhost("localhost."),
diff -Nru pdns-recursor-4.0.4/debian/patches/series
pdns-recursor-4.0.4/debian/patches/series
--- pdns-recursor-4.0.4/debian/patches/series 2017-12-07 12:40:02.000000000
+0000
+++ pdns-recursor-4.0.4/debian/patches/series 2018-11-10 16:05:33.000000000
+0000
@@ -4,3 +4,6 @@
CVE-2017-15093-4.0.6.patch
CVE-2017-15094-4.0.6.patch
CVE-2017-15120.patch
+CVE-2018-10851-rec-4.0.8.patch
+CVE-2018-14626-rec-4.0.8.patch
+CVE-2018-14644-rec-4.0.4.patch
--- End Message ---