From aecc27189f6288237a0559b6fad2dcd09f1fb1e2 Mon Sep 17 00:00:00 2001 From: Evan Hunt Date: Tue, 17 Mar 2026 13:45:11 -0700 Subject: [PATCH] Test UPDATE behavior in CHAOS and other non-IN classes Send various UPDATE requests that are known to have caused crashes previously with deliberately misconfigured non-IN zones; confirm that UPDATE is not processed. (cherry picked from commit e2f7ba2a4b6e7e5dba2fb1a2c9b2f0323e9a88be) --- bin/named/server.c | 1 - bin/tests/system/class/ns2/localhost.db.in | 5 + bin/tests/system/class/tests_class_update.py | 96 ++++++++++++++++++++ 3 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 bin/tests/system/class/tests_class_update.py diff --git a/bin/named/server.c b/bin/named/server.c index 63bb311d3a..df4bb6ff4f 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -5392,7 +5392,6 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config, &view->proxyonacl)); if (view->rdclass != dns_rdataclass_in) { - view->recursion = false; dns_acl_none(named_g_mctx, &view->recursionacl); dns_acl_none(named_g_mctx, &view->recursiononacl); } else { diff --git a/bin/tests/system/class/ns2/localhost.db.in b/bin/tests/system/class/ns2/localhost.db.in index baa5f74862..a50e5167a9 100644 --- a/bin/tests/system/class/ns2/localhost.db.in +++ b/bin/tests/system/class/ns2/localhost.db.in @@ -3,4 +3,9 @@ $TTL 300 @ IN SOA ns hostmaster 1 3600 900 604800 300 @ IN NS ns ns IN A 127.0.0.1 + @ IN KX 10 target.example. +@ IN PX 10 map822.example. mapx400.example. +@ IN NSAP 0x47000580ffff0000000001e133ffffff00016200 +@ IN NSAP-PTR target.example. +@ in EID \# 01 aa diff --git a/bin/tests/system/class/tests_class_update.py b/bin/tests/system/class/tests_class_update.py new file mode 100644 index 0000000000..e53bbc77ea --- /dev/null +++ b/bin/tests/system/class/tests_class_update.py @@ -0,0 +1,96 @@ +# Copyright (C) Internet Systems Consortium, Inc. ("ISC") +# +# SPDX-License-Identifier: MPL-2.0 +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, you can obtain one at https://mozilla.org/MPL/2.0/. +# +# See the COPYRIGHT file distributed with this work for additional +# information regarding copyright ownership. + +import socket +import struct + +from dns import rdataclass, rdatatype, update + +import pytest + +import isctest + +pytestmark = pytest.mark.extra_artifacts( + [ + "*/*.db", + ] +) + + +def encode_name(name: str) -> bytes: + out = b"" + for label in name.rstrip(".").split("."): + out += bytes([len(label)]) + label.encode("ascii") + return out + b"\x00" + + +@pytest.mark.parametrize( + "rdtype,rdclass,ttl,rdata", + [ + (rdatatype.SRV, rdataclass.NONE, 0, b"\x00"), + (rdatatype.KX, rdataclass.NONE, 0, b""), + (rdatatype.PX, rdataclass.NONE, 0, b""), + (rdatatype.NSAP, rdataclass.NONE, 0, b""), + (rdatatype.NSAP_PTR, rdataclass.NONE, 0, b""), + (31, rdataclass.NONE, 0, b""), # dnspython doesn't define type EID + ], +) +def test_class_invalid(rdtype, rdclass, ttl, rdata, named_port): + # these update messages are badly formatted, so we construct + # them manually instead of using dnspython. + + # opcode=UPDATE, 1 RRset in ZONE, 1 RRset in UPDATE + header = struct.pack("!HHHHHH", 0, 0x2800, 1, 0, 1, 0) + + # ZONE section: QNAME=, QTYPE=SOA, QCLASS=ANY + zone_q = encode_name("1.0.0.127.in-addr.arpa") + struct.pack("!HH", 6, 255) + + # UPDATE section RR: + update_rr = ( + encode_name("1.0.0.127.in-addr.arpa") + + struct.pack("!HHIH", rdtype, rdclass, ttl, len(rdata)) + + rdata + ) + + m = header + zone_q + update_rr + packet = struct.pack("!H", len(m)) + m + + with socket.create_connection( + ("10.53.0.2", named_port), source_address=("127.0.0.1", 0), timeout=2.0 + ) as s: + s.sendall(packet) + try: + rwire = s.recv(4096) + res = dns.message.from_wire(rwire) + isctest.check.formerr(res) + except Exception: # pylint: disable=broad-except + pass + + # check the server is answering + msg = isctest.query.create("1.0.0.127.in-addr.arpa", "SRV") + res = isctest.query.udp(msg, "10.53.0.2") + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.answer, 0) + + +@pytest.mark.parametrize( + "rdtype,rdata", + [ + (rdatatype.SVCB, "\\# 02 0000"), + (rdatatype.WKS, "\\# 02 4142"), + (rdatatype.WKS, "\\# 02 4344"), + ], +) +def test_class_chaosupdate(rdtype, rdata): + up = update.UpdateMessage("example.", rdclass=rdataclass.CHAOS) + up.add("foo.example.", 300, rdtype, rdata) + res = isctest.query.tcp(up, "10.53.0.2") + isctest.check.notimp(res)