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

Bug#970745: buster-pu: package pdns_4.1.6-3+deb10u1



Package: release.debian.org
Severity: normal
Tags: buster
User: release.debian.org@packages.debian.org
Usertags: pu

Fixes for low-severity issues CVE-2019-10203 and CVE-2020-17482.
Both using upstream patches for the 4.1 branch.

Maybe it should be pointed out in the stable update notes that
manual action is needed to remedy CVE-2019-10203 for existing
installations using postgres. "Manual schema update required for
PostgreSQL"?

Chris


diff -Nru pdns-4.1.6/debian/changelog pdns-4.1.6/debian/changelog
--- pdns-4.1.6/debian/changelog	2019-06-21 19:07:07.000000000 +0000
+++ pdns-4.1.6/debian/changelog	2020-09-22 19:07:45.000000000 +0000
@@ -1,3 +1,13 @@
+pdns (4.1.6-3+deb10u1) buster; urgency=medium
+
+  * Apply upstream patches to fix CVE-2019-10203.
+    To actually fix this problem in existing installations, the newly
+    supplied schema file 4.1.10_to_4.1.11.schema.pgsql.sql has to be
+    manually applied to the backing PostgreSQL database. (Closes: #970729)
+  * Apply upstream patches to fix CVE-2020-17482 (Closes: #970737)
+
+ -- Chris Hofstaedtler <zeha@debian.org>  Tue, 22 Sep 2020 19:07:45 +0000
+
 pdns (4.1.6-3) unstable; urgency=medium
 
   * Fix Denial of service via crafted zone records (CVE-2019-10162)
diff -Nru pdns-4.1.6/debian/patches/CVE-2019-10203.patch pdns-4.1.6/debian/patches/CVE-2019-10203.patch
--- pdns-4.1.6/debian/patches/CVE-2019-10203.patch	1970-01-01 00:00:00.000000000 +0000
+++ pdns-4.1.6/debian/patches/CVE-2019-10203.patch	2020-09-22 19:07:45.000000000 +0000
@@ -0,0 +1,54 @@
+From 6b48327a0da913d8eeb1c1a4938d3f22d80f9fb3 Mon Sep 17 00:00:00 2001
+From: Peter van Dijk <peter.van.dijk@powerdns.com>
+Date: Tue, 30 Jul 2019 15:40:09 +0200
+Subject: [PATCH] adjust gpgsql schema for advisory 2019-06
+
+---
+ modules/gpgsqlbackend/4.1.10_to_4.1.11.schema.pgsql.sql | 1 +
+ modules/gpgsqlbackend/schema.pgsql.sql                  | 2 +-
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+ create mode 100644 modules/gpgsqlbackend/4.1.10_to_4.1.11.schema.pgsql.sql
+
+diff --git a/modules/gpgsqlbackend/4.1.10_to_4.1.11.schema.pgsql.sql b/modules/gpgsqlbackend/4.1.10_to_4.1.11.schema.pgsql.sql
+new file mode 100644
+index 0000000000..b0c2ee1efa
+--- /dev/null
++++ b/modules/gpgsqlbackend/4.1.10_to_4.1.11.schema.pgsql.sql
+@@ -0,0 +1 @@
++ALTER TABLE domains ALTER notified_serial TYPE bigint USING CASE WHEN notified_serial >= 0 THEN notified_serial::bigint END;
+diff --git a/modules/gpgsqlbackend/schema.pgsql.sql b/modules/gpgsqlbackend/schema.pgsql.sql
+index b105d87951..cad35d5f19 100644
+--- a/modules/gpgsqlbackend/schema.pgsql.sql
++++ b/modules/gpgsqlbackend/schema.pgsql.sql
+@@ -4,7 +4,7 @@ CREATE TABLE domains (
+   master                VARCHAR(128) DEFAULT NULL,
+   last_check            INT DEFAULT NULL,
+   type                  VARCHAR(6) NOT NULL,
+-  notified_serial       INT DEFAULT NULL,
++  notified_serial       BIGINT DEFAULT NULL,
+   account               VARCHAR(40) DEFAULT NULL,
+   CONSTRAINT c_lowercase_name CHECK (((name)::TEXT = LOWER((name)::TEXT)))
+ );
+
+
+From 15b1f3607691e6b0443696d6edca40cc3a04bbb0 Mon Sep 17 00:00:00 2001
+From: tcely <tcely@users.noreply.github.com>
+Date: Sun, 4 Aug 2019 05:12:30 -0400
+Subject: [PATCH] gpgsqlbackend: add missing schema file to Makefile
+
+---
+ modules/gpgsqlbackend/Makefile.am | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/modules/gpgsqlbackend/Makefile.am b/modules/gpgsqlbackend/Makefile.am
+index 8a820d516b..9e2f271702 100644
+--- a/modules/gpgsqlbackend/Makefile.am
++++ b/modules/gpgsqlbackend/Makefile.am
+@@ -12,6 +12,7 @@ dist_doc_DATA = \
+ 	schema.pgsql.sql \
+ 	nodnssec-3.x_to_3.4.0_schema.pgsql.sql \
+ 	dnssec-3.x_to_3.4.0_schema.pgsql.sql \
++	4.1.10_to_4.1.11.schema.pgsql.sql \
+ 	3.4.0_to_4.1.0_schema.pgsql.sql
+ 
+ libgpgsqlbackend_la_SOURCES = \
diff -Nru pdns-4.1.6/debian/patches/CVE-2020-17482.patch pdns-4.1.6/debian/patches/CVE-2020-17482.patch
--- pdns-4.1.6/debian/patches/CVE-2020-17482.patch	1970-01-01 00:00:00.000000000 +0000
+++ pdns-4.1.6/debian/patches/CVE-2020-17482.patch	2020-09-22 19:07:45.000000000 +0000
@@ -0,0 +1,153 @@
+From 3b88cb8c8cdd166b566ef7bd87f47732b2783f6a Mon Sep 17 00:00:00 2001
+From: Remi Gacogne <remi.gacogne@powerdns.com>
+Date: Tue, 11 Aug 2020 11:25:06 +0200
+Subject: [PATCH 1/2] Raise an exception on invalid hex content in unknown
+ records
+
+Otherwise we can end up reading uninitialised memory from the stack,
+possibly leaking information.
+This is only an issue if the content is read from an untrusted source
+and can be passed back to an attacker.
+---
+ pdns/dnsparser.cc          | 24 ++++++++++++++++--------
+ pdns/test-dnsrecords_cc.cc | 32 ++++++++++++++++++++++++++++++++
+ 2 files changed, 48 insertions(+), 8 deletions(-)
+
+diff --git a/pdns/dnsparser.cc b/pdns/dnsparser.cc
+index b6108d8c6b..3a4e193f01 100644
+--- a/pdns/dnsparser.cc
++++ b/pdns/dnsparser.cc
+@@ -40,17 +40,25 @@ class UnknownRecordContent : public DNSRecordContent
+     // parse the input
+     vector<string> parts;
+     stringtok(parts, zone);
+-    if(parts.size()!=3 && !(parts.size()==2 && equals(parts[1],"0")) )
+-      throw MOADNSException("Unknown record was stored incorrectly, need 3 fields, got "+std::to_string(parts.size())+": "+zone );
+-    const string& relevant=(parts.size() > 2) ? parts[2] : "";
+-    unsigned int total=pdns_stou(parts[1]);
+-    if(relevant.size() % 2 || relevant.size() / 2 != total)
++    // we need exactly 3 parts, except if the length field is set to 0 then we only need 2
++    if (parts.size() != 3 && !(parts.size() == 2 && equals(parts[1], "0"))) {
++      throw MOADNSException("Unknown record was stored incorrectly, need 3 fields, got " + std::to_string(parts.size()) + ": " + zone);
++    }
++
++    const string& relevant = (parts.size() > 2) ? parts[2] : "";
++    unsigned int total = pdns_stou(parts[1]);
++    if (relevant.size() % 2 || (relevant.size() / 2) != total) {
+       throw MOADNSException((boost::format("invalid unknown record length: size not equal to length field (%d != 2 * %d)") % relevant.size() % total).str());
++    }
++
+     string out;
+-    out.reserve(total+1);
+-    for(unsigned int n=0; n < total; ++n) {
++    out.reserve(total + 1);
++
++    for (unsigned int n = 0; n < total; ++n) {
+       int c;
+-      sscanf(relevant.c_str()+2*n, "%02x", &c);
++      if (sscanf(relevant.c_str()+2*n, "%02x", &c) != 1) {
++        throw MOADNSException("unable to read data at position " + std::to_string(2 * n) + " from unknown record of size " + std::to_string(relevant.size()));
++      }
+       out.append(1, (char)c);
+     }
+ 
+diff --git a/pdns/test-dnsrecords_cc.cc b/pdns/test-dnsrecords_cc.cc
+index df4102a4fb..854de2125e 100644
+--- a/pdns/test-dnsrecords_cc.cc
++++ b/pdns/test-dnsrecords_cc.cc
+@@ -327,4 +327,36 @@ BOOST_AUTO_TEST_CASE(test_opt_record_out) {
+   BOOST_CHECK_EQUAL(makeHexDump(std::string(pak.begin(),pak.end())), makeHexDump(packet));
+ }
+ 
++// special record test, because Unknown record types are the worst
++BOOST_AUTO_TEST_CASE(test_unknown_records_in) {
++
++  auto validUnknown = DNSRecordContent::mastermake(static_cast<QType::typeenum>(65534), QClass::IN, "\\# 1 42");
++
++  // we need at least two parts
++  BOOST_CHECK_THROW(auto notEnoughPartsUnknown = DNSRecordContent::mastermake(static_cast<QType::typeenum>(65534), QClass::IN, "\\#"), MOADNSException);
++
++  // two parts are OK when the RDATA size is 0, not OK otherwise
++  auto validEmptyUnknown = DNSRecordContent::mastermake(static_cast<QType::typeenum>(65534), QClass::IN, "\\# 0");
++  BOOST_CHECK_THROW(auto twoPartsNotZeroUnknown = DNSRecordContent::mastermake(static_cast<QType::typeenum>(65534), QClass::IN, "\\# 1"), MOADNSException);
++
++  // RDATA length is not even
++  BOOST_CHECK_THROW(auto unevenUnknown = DNSRecordContent::mastermake(static_cast<QType::typeenum>(65534), QClass::IN, "\\# 1 A"), MOADNSException);
++
++  // RDATA length is not equal to the expected size
++  BOOST_CHECK_THROW(auto wrongRDATASizeUnknown = DNSRecordContent::mastermake(static_cast<QType::typeenum>(65534), QClass::IN, "\\# 2 AA"), MOADNSException);
++
++  // RDATA is invalid (invalid hex value)
++  try {
++    auto invalidRDATAUnknown = DNSRecordContent::mastermake(static_cast<QType::typeenum>(65534), QClass::IN, "\\# 1 JJ");
++    // we should not reach that code
++    BOOST_CHECK(false);
++    // but if we do let's see what we got (likely what was left over on the stack)
++    BOOST_CHECK_EQUAL(invalidRDATAUnknown->getZoneRepresentation(), "\\# 1 jj");
++  }
++  catch (const MOADNSException& e)
++  {
++    // it's expected to end up there
++  }
++}
++
+ BOOST_AUTO_TEST_SUITE_END()
+
+From 11e1d5c7b676c1f51365b54aada0af4f63852ea0 Mon Sep 17 00:00:00 2001
+From: Remi Gacogne <remi.gacogne@powerdns.com>
+Date: Tue, 11 Aug 2020 14:07:32 +0200
+Subject: [PATCH 2/2] Raise an exception on invalid first part (!= \#) in
+ unknown records
+
+---
+ pdns/dnsparser.cc          | 12 ++++++++----
+ pdns/test-dnsrecords_cc.cc |  3 +++
+ 2 files changed, 11 insertions(+), 4 deletions(-)
+
+diff --git a/pdns/dnsparser.cc b/pdns/dnsparser.cc
+index 3a4e193f01..356e4a6cef 100644
+--- a/pdns/dnsparser.cc
++++ b/pdns/dnsparser.cc
+@@ -41,12 +41,16 @@ class UnknownRecordContent : public DNSRecordContent
+     vector<string> parts;
+     stringtok(parts, zone);
+     // we need exactly 3 parts, except if the length field is set to 0 then we only need 2
+-    if (parts.size() != 3 && !(parts.size() == 2 && equals(parts[1], "0"))) {
++    if (parts.size() != 3 && !(parts.size() == 2 && equals(parts.at(1), "0"))) {
+       throw MOADNSException("Unknown record was stored incorrectly, need 3 fields, got " + std::to_string(parts.size()) + ": " + zone);
+     }
+ 
+-    const string& relevant = (parts.size() > 2) ? parts[2] : "";
+-    unsigned int total = pdns_stou(parts[1]);
++    if (parts.at(0) != "\\#") {
++      throw MOADNSException("Unknown record was stored incorrectly, first part should be '\\#', got '" + parts.at(0) + "'");
++    }
++
++    const string& relevant = (parts.size() > 2) ? parts.at(2) : "";
++    unsigned int total = pdns_stou(parts.at(1));
+     if (relevant.size() % 2 || (relevant.size() / 2) != total) {
+       throw MOADNSException((boost::format("invalid unknown record length: size not equal to length field (%d != 2 * %d)") % relevant.size() % total).str());
+     }
+@@ -56,7 +60,7 @@ class UnknownRecordContent : public DNSRecordContent
+ 
+     for (unsigned int n = 0; n < total; ++n) {
+       int c;
+-      if (sscanf(relevant.c_str()+2*n, "%02x", &c) != 1) {
++      if (sscanf(&relevant.at(2*n), "%02x", &c) != 1) {
+         throw MOADNSException("unable to read data at position " + std::to_string(2 * n) + " from unknown record of size " + std::to_string(relevant.size()));
+       }
+       out.append(1, (char)c);
+diff --git a/pdns/test-dnsrecords_cc.cc b/pdns/test-dnsrecords_cc.cc
+index 854de2125e..770102f1fd 100644
+--- a/pdns/test-dnsrecords_cc.cc
++++ b/pdns/test-dnsrecords_cc.cc
+@@ -339,6 +339,9 @@ BOOST_AUTO_TEST_CASE(test_unknown_records_in) {
+   auto validEmptyUnknown = DNSRecordContent::mastermake(static_cast<QType::typeenum>(65534), QClass::IN, "\\# 0");
+   BOOST_CHECK_THROW(auto twoPartsNotZeroUnknown = DNSRecordContent::mastermake(static_cast<QType::typeenum>(65534), QClass::IN, "\\# 1"), MOADNSException);
+ 
++  // the first part has to be "\#"
++  BOOST_CHECK_THROW(auto invalidFirstPartUnknown = DNSRecordContent::mastermake(static_cast<QType::typeenum>(65534), QClass::IN, "\\$ 0"), MOADNSException);
++
+   // RDATA length is not even
+   BOOST_CHECK_THROW(auto unevenUnknown = DNSRecordContent::mastermake(static_cast<QType::typeenum>(65534), QClass::IN, "\\# 1 A"), MOADNSException);
+ 
diff -Nru pdns-4.1.6/debian/patches/series pdns-4.1.6/debian/patches/series
--- pdns-4.1.6/debian/patches/series	2019-06-21 19:07:07.000000000 +0000
+++ pdns-4.1.6/debian/patches/series	2020-09-22 19:07:45.000000000 +0000
@@ -1,3 +1,5 @@
 CVE-2019-3871-auth-4.1.6.patch
 CVE-2019-10162-4.1.8-invalidrecords.patch
 CVE-2019-10163-4.1.8-busyloop.patch
+CVE-2019-10203.patch
+CVE-2020-17482.patch


Reply to: