Your message dated Sat, 09 Mar 2019 16:44:28 +0000
with message-id <1552149868.11727.49.ca...@adam-barratt.org.uk>
and subject line Re: Bug#915667: pdns-recursor 4.0.4-1+deb9u4 flagged for 
acceptance
has caused the Debian Bug report #915667,
regarding stretch-pu: package pdns-recursor/4.0.4-1+deb9u4
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact ow...@bugs.debian.org
immediately.)


-- 
915667: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=915667
Debian Bug Tracking System
Contact ow...@bugs.debian.org with problems
--- 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 ---
--- Begin Message ---
Version: 9.8

On Thu, 2019-01-03 at 21:34 +0000, Adam D Barratt wrote:
> Control: tags -1 + pending
> 
> Hi,
> 
> The upload referenced by this bug report has been flagged for
> acceptance into the proposed-updates queue for Debian stretch.
> 
> Thanks for your contribution!
> 
> Upload details
> ==============
> 
> Package: pdns-recursor
> Version: 4.0.4-1+deb9u4
> 
> Explanation: fix security issues [CVE-2018-10851 CVE-2018-14626 CVE-
> 2018-14644]

This was actually included in 9.8, but the re-opening after the
accidental closure removed the "pending" tag, so we missed it when
cleaning up.

Regards,

Adam

--- End Message ---

Reply via email to