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

Bug#926097: unblock: pdns/4.1.6-2



Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock

Dear Release Team,

Please unblock package pdns 4.1.6-2, which has a security fix for
CVE-2019-3871 (#924966), prepared and tested by Salvatore (and
checked by me).

unblock pdns/4.1.6-2

Thanks,
Chris

debdiff follows:


diff -Nru pdns-4.1.6/debian/changelog pdns-4.1.6/debian/changelog
--- pdns-4.1.6/debian/changelog	2019-02-03 14:20:23.000000000 +0000
+++ pdns-4.1.6/debian/changelog	2019-03-31 12:48:59.000000000 +0000
@@ -1,3 +1,11 @@
+pdns (4.1.6-2) unstable; urgency=high
+
+  [ Salvatore Bonaccorso ]
+  * Insufficient validation in the HTTP remote backend (CVE-2019-3871)
+    (Closes: #924966)
+
+ -- Chris Hofstaedtler <zeha@debian.org>  Sun, 31 Mar 2019 12:48:59 +0000
+
 pdns (4.1.6-1) unstable; urgency=medium
 
   * New upstream version 4.1.6
diff -Nru pdns-4.1.6/debian/patches/CVE-2019-3871-auth-4.1.6.patch pdns-4.1.6/debian/patches/CVE-2019-3871-auth-4.1.6.patch
--- pdns-4.1.6/debian/patches/CVE-2019-3871-auth-4.1.6.patch	1970-01-01 00:00:00.000000000 +0000
+++ pdns-4.1.6/debian/patches/CVE-2019-3871-auth-4.1.6.patch	2019-03-31 12:48:59.000000000 +0000
@@ -0,0 +1,147 @@
+Description: Insufficient validation in the HTTP remote backend
+Origin: upstream, https://downloads.powerdns.com/patches/2019-03/CVE-2019-3871-auth-4.1.6.patch
+Bug: https://github.com/PowerDNS/pdns/issues/7573
+Bug-Debian: https://bugs.debian.org/924966
+Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2019-3871
+Forwarded: not-needed
+Reviewed-by: Salvatore Bonaccorso <carnil@debian.org>
+Last-Update: 2019-03-29
+Applied-Upstream: 4.1.7
+
+diff -ru pdns-4.1.6.orig/modules/remotebackend/httpconnector.cc pdns-4.1.6/modules/remotebackend/httpconnector.cc
+--- pdns-4.1.6.orig/modules/remotebackend/httpconnector.cc	2019-01-31 10:17:33.000000000 +0100
++++ pdns-4.1.6/modules/remotebackend/httpconnector.cc	2019-03-15 13:29:51.102891481 +0100
+@@ -35,7 +35,22 @@
+ #endif
+ 
+ HTTPConnector::HTTPConnector(std::map<std::string,std::string> options) {
++
++    if (options.find("url") == options.end()) {
++      throw PDNSException("Cannot find 'url' option in the remote backend HTTP connector's parameters");
++    }
++
+     this->d_url = options.find("url")->second;
++
++    try {
++      YaHTTP::URL url(d_url);
++      d_host = url.host;
++      d_port = url.port;
++    }
++    catch(const std::exception& e) {
++      throw PDNSException("Error parsing the 'url' option provided to the remote backend HTTP connector: " + std::string(e.what()));
++    }
++
+     if (options.find("url-suffix") != options.end()) {
+       this->d_url_suffix = options.find("url-suffix")->second;
+     } else {
+@@ -71,7 +86,7 @@
+ void HTTPConnector::addUrlComponent(const Json &parameters, const string& element, std::stringstream& ss) {
+     std::string sparam;
+     if (parameters[element] != Json())
+-       ss << "/" << asString(parameters[element]);
++       ss << "/" << YaHTTP::Utility::encodeURL(asString(parameters[element]), false);
+ }
+ 
+ std::string HTTPConnector::buildMemberListArgs(std::string prefix, const Json& args) {
+@@ -81,9 +96,9 @@
+         if (pair.second.is_bool()) {
+           stream << (pair.second.bool_value()?"1":"0");
+         } else if (pair.second.is_null()) {
+-          stream << prefix << "[" << pair.first << "]=";
++          stream << prefix << "[" << YaHTTP::Utility::encodeURL(pair.first, false) << "]=";
+         } else {
+-          stream << prefix << "[" << pair.first << "]=" << this->asString(pair.second);
++          stream << prefix << "[" << YaHTTP::Utility::encodeURL(pair.first, false) << "]=" << YaHTTP::Utility::encodeURL(this->asString(pair.second), false);
+         }
+         stream << "&";
+     }
+@@ -334,45 +349,41 @@
+     delete this->d_socket;
+     this->d_socket = NULL;
+ 
+-    if (req.url.protocol == "unix") {
+-      // connect using unix socket
+-    } else {
+-      // connect using tcp
+-      struct addrinfo *gAddr, *gAddrPtr, hints;
+-      std::string sPort = std::to_string(req.url.port);
+-      memset(&hints,0,sizeof hints);
+-      hints.ai_family = AF_UNSPEC;
+-      hints.ai_flags = AI_ADDRCONFIG; 
+-      hints.ai_socktype = SOCK_STREAM;
+-      hints.ai_protocol = 6; // tcp
+-      if ((ec = getaddrinfo(req.url.host.c_str(), sPort.c_str(), &hints, &gAddr)) == 0) {
+-        // try to connect to each address. 
+-        gAddrPtr = gAddr;
++    // connect using tcp
++    struct addrinfo *gAddr, *gAddrPtr, hints;
++    std::string sPort = std::to_string(d_port);
++    memset(&hints,0,sizeof hints);
++    hints.ai_family = AF_UNSPEC;
++    hints.ai_flags = AI_ADDRCONFIG; 
++    hints.ai_socktype = SOCK_STREAM;
++    hints.ai_protocol = 6; // tcp
++    if ((ec = getaddrinfo(d_host.c_str(), sPort.c_str(), &hints, &gAddr)) == 0) {
++      // try to connect to each address. 
++      gAddrPtr = gAddr;
+   
+-        while(gAddrPtr) {
+-          try {
+-            d_socket = new Socket(gAddrPtr->ai_family, gAddrPtr->ai_socktype, gAddrPtr->ai_protocol);
+-            d_addr.setSockaddr(gAddrPtr->ai_addr, gAddrPtr->ai_addrlen);
+-            d_socket->connect(d_addr);
+-            d_socket->setNonBlocking();
+-            d_socket->writenWithTimeout(out.str().c_str(), out.str().size(), timeout);
+-            rv = 1;
+-          } catch (NetworkError& ne) {
+-            L<<Logger::Error<<"While writing to HTTP endpoint "<<d_addr.toStringWithPort()<<": "<<ne.what()<<std::endl;
+-          } catch (...) {
+-            L<<Logger::Error<<"While writing to HTTP endpoint "<<d_addr.toStringWithPort()<<": exception caught"<<std::endl;
+-          }
+-
+-          if (rv > -1) break;
+-          delete d_socket;
+-          d_socket = NULL;
+-          gAddrPtr = gAddrPtr->ai_next;
+-          
++      while(gAddrPtr) {
++        try {
++          d_socket = new Socket(gAddrPtr->ai_family, gAddrPtr->ai_socktype, gAddrPtr->ai_protocol);
++          d_addr.setSockaddr(gAddrPtr->ai_addr, gAddrPtr->ai_addrlen);
++          d_socket->connect(d_addr);
++          d_socket->setNonBlocking();
++          d_socket->writenWithTimeout(out.str().c_str(), out.str().size(), timeout);
++          rv = 1;
++        } catch (NetworkError& ne) {
++          L<<Logger::Error<<"While writing to HTTP endpoint "<<d_addr.toStringWithPort()<<": "<<ne.what()<<std::endl;
++        } catch (...) {
++          L<<Logger::Error<<"While writing to HTTP endpoint "<<d_addr.toStringWithPort()<<": exception caught"<<std::endl;
+         }
+-        freeaddrinfo(gAddr);
+-      } else {
+-        L<<Logger::Error<<"Unable to resolve " << req.url.host << ": " << gai_strerror(ec) << std::endl;
++
++        if (rv > -1) break;
++        delete d_socket;
++        d_socket = NULL;
++        gAddrPtr = gAddrPtr->ai_next;
++          
+       }
++      freeaddrinfo(gAddr);
++    } else {
++      L<<Logger::Error<<"Unable to resolve " << d_host << ": " << gai_strerror(ec) << std::endl;
+     }
+ 
+     return rv;
+diff -ru pdns-4.1.6.orig/modules/remotebackend/remotebackend.hh pdns-4.1.6/modules/remotebackend/remotebackend.hh
+--- pdns-4.1.6.orig/modules/remotebackend/remotebackend.hh	2019-01-31 10:17:33.000000000 +0100
++++ pdns-4.1.6/modules/remotebackend/remotebackend.hh	2019-03-15 13:29:51.102891481 +0100
+@@ -104,6 +104,8 @@
+     std::string buildMemberListArgs(std::string prefix, const Json& args);
+     Socket* d_socket;
+     ComboAddress d_addr;
++    std::string d_host;
++    uint16_t d_port;
+ };
+ 
+ #ifdef REMOTEBACKEND_ZEROMQ
diff -Nru pdns-4.1.6/debian/patches/series pdns-4.1.6/debian/patches/series
--- pdns-4.1.6/debian/patches/series	1970-01-01 00:00:00.000000000 +0000
+++ pdns-4.1.6/debian/patches/series	2019-03-31 12:48:59.000000000 +0000
@@ -0,0 +1 @@
+CVE-2019-3871-auth-4.1.6.patch


Reply to: