93 lines
3.5 KiB
Diff
93 lines
3.5 KiB
Diff
From bf596c14c2462b9a15ea738ef4f32b3abb8b63d1 Mon Sep 17 00:00:00 2001
|
|
From: Aaron Haslett <aaronhaslett@catalyst.net.nz>
|
|
Date: Tue, 23 Oct 2018 17:25:51 +1300
|
|
Subject: [PATCH 01/17] CVE-2018-14629 dns: CNAME loop prevention using counter
|
|
|
|
Count number of answers generated by internal DNS query routine and stop at
|
|
20 to match Microsoft's loop prevention mechanism.
|
|
|
|
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13600
|
|
|
|
Signed-off-by: Aaron Haslett <aaronhaslett@catalyst.net.nz>
|
|
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
|
|
Reviewed-by: Garming Sam <garming@catalyst.net.nz>
|
|
---
|
|
python/samba/tests/dns.py | 22 ++++++++++++++++++++++
|
|
selftest/knownfail.d/dns | 6 ++++++
|
|
source4/dns_server/dns_query.c | 6 ++++++
|
|
3 files changed, 34 insertions(+)
|
|
|
|
diff --git a/python/samba/tests/dns.py b/python/samba/tests/dns.py
|
|
index 6771e3bb8c4..3e6306e2be8 100644
|
|
--- a/python/samba/tests/dns.py
|
|
+++ b/python/samba/tests/dns.py
|
|
@@ -844,6 +844,28 @@ class TestComplexQueries(DNSTest):
|
|
self.assertEquals(response.answers[1].name, name2)
|
|
self.assertEquals(response.answers[1].rdata, name0)
|
|
|
|
+ def test_cname_loop(self):
|
|
+ cname1 = "cnamelooptestrec." + self.get_dns_domain()
|
|
+ cname2 = "cnamelooptestrec2." + self.get_dns_domain()
|
|
+ cname3 = "cnamelooptestrec3." + self.get_dns_domain()
|
|
+ self.make_dns_update(cname1, cname2, dnsp.DNS_TYPE_CNAME)
|
|
+ self.make_dns_update(cname2, cname3, dnsp.DNS_TYPE_CNAME)
|
|
+ self.make_dns_update(cname3, cname1, dnsp.DNS_TYPE_CNAME)
|
|
+
|
|
+ p = self.make_name_packet(dns.DNS_OPCODE_QUERY)
|
|
+ questions = []
|
|
+
|
|
+ q = self.make_name_question(cname1,
|
|
+ dns.DNS_QTYPE_A,
|
|
+ dns.DNS_QCLASS_IN)
|
|
+ questions.append(q)
|
|
+ self.finish_name_packet(p, questions)
|
|
+
|
|
+ (response, response_packet) =\
|
|
+ self.dns_transaction_udp(p, host=self.server_ip)
|
|
+
|
|
+ max_recursion_depth = 20
|
|
+ self.assertEquals(len(response.answers), max_recursion_depth)
|
|
|
|
class TestInvalidQueries(DNSTest):
|
|
def setUp(self):
|
|
diff --git a/selftest/knownfail.d/dns b/selftest/knownfail.d/dns
|
|
index a5176654cc2..a248432aafa 100644
|
|
--- a/selftest/knownfail.d/dns
|
|
+++ b/selftest/knownfail.d/dns
|
|
@@ -69,3 +69,9 @@ samba.tests.dns.__main__.TestSimpleQueries.test_qtype_all_query\(rodc:local\)
|
|
|
|
# The SOA override should not pass against the RODC, it must not overstamp
|
|
samba.tests.dns.__main__.TestSimpleQueries.test_one_SOA_query\(rodc:local\)
|
|
+
|
|
+#
|
|
+# rodc and vampire_dc require signed dns updates, so the test setup
|
|
+# fails, but the test does run on fl2003dc
|
|
+^samba.tests.dns.__main__.TestComplexQueries.test_cname_loop\(rodc:local\)
|
|
+^samba.tests.dns.__main__.TestComplexQueries.test_cname_loop\(vampire_dc:local\)
|
|
diff --git a/source4/dns_server/dns_query.c b/source4/dns_server/dns_query.c
|
|
index 923f7233eb9..65faeac3b6a 100644
|
|
--- a/source4/dns_server/dns_query.c
|
|
+++ b/source4/dns_server/dns_query.c
|
|
@@ -40,6 +40,7 @@
|
|
|
|
#undef DBGC_CLASS
|
|
#define DBGC_CLASS DBGC_DNS
|
|
+#define MAX_Q_RECURSION_DEPTH 20
|
|
|
|
struct forwarder_string {
|
|
const char *forwarder;
|
|
@@ -419,6 +420,11 @@ static struct tevent_req *handle_dnsrpcrec_send(
|
|
state->answers = answers;
|
|
state->nsrecs = nsrecs;
|
|
|
|
+ if (talloc_array_length(*answers) >= MAX_Q_RECURSION_DEPTH) {
|
|
+ tevent_req_done(req);
|
|
+ return tevent_req_post(req, ev);
|
|
+ }
|
|
+
|
|
resolve_cname = ((rec->wType == DNS_TYPE_CNAME) &&
|
|
((question->question_type == DNS_QTYPE_A) ||
|
|
(question->question_type == DNS_QTYPE_AAAA)));
|
|
--
|
|
2.17.1
|