[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#915667: stretch-pu: package pdns-recursor/4.0.4-1+deb9u4



Package: release.debian.org
Severity: normal
Tags: stretch
User: release.debian.org@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 <zeha@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.hofstaedtler@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


Reply to: