Commit bbe5d2a7 authored by Aaron Haslett's avatar Aaron Haslett Committed by Mathieu Parent

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=13600Signed-off-by: default avatarAaron Haslett <aaronhaslett@catalyst.net.nz>
Reviewed-by: default avatarAndrew Bartlett <abartlet@samba.org>
Reviewed-by: default avatarGarming Sam <garming@catalyst.net.nz>
parent c1f2485d
......@@ -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):
......
......@@ -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\)
......@@ -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)));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment