]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add leak test
authorAlessio Podda <alessio@isc.org>
Wed, 8 Apr 2026 07:26:51 +0000 (09:26 +0200)
committerAlessio Podda <alessio@isc.org>
Mon, 11 May 2026 08:28:20 +0000 (10:28 +0200)
Add a test to ensure that the rdataset queried when adding glue is not
leaked.

bin/tests/system/gluecache/ns1/example.db [new file with mode: 0644]
bin/tests/system/gluecache/ns1/named.conf.j2 [new file with mode: 0644]
bin/tests/system/gluecache/tests_gluecache.py [new file with mode: 0644]

diff --git a/bin/tests/system/gluecache/ns1/example.db b/bin/tests/system/gluecache/ns1/example.db
new file mode 100644 (file)
index 0000000..9384c52
--- /dev/null
@@ -0,0 +1,19 @@
+$TTL 300
+$ORIGIN example.
+@      IN SOA  ns.example. admin.example. (
+                       2026040100      ; serial
+                       3600            ; refresh
+                       1800            ; retry
+                       604800          ; expire
+                       300             ; minimum
+                       )
+       NS      ns.example.
+
+ns     A       10.53.0.1
+ns     AAAA    fd92:7065:b8e:ffff::1
+
+; Delegation whose NS target is in-zone authoritative data (NOT glue).
+; The NS target ns.example. is at the zone apex, not below any zone cut,
+; so qpzone_find will return ISC_R_SUCCESS rather than DNS_R_GLUE when
+; looking up the glue for this delegation.
+sub    NS      ns.example.
diff --git a/bin/tests/system/gluecache/ns1/named.conf.j2 b/bin/tests/system/gluecache/ns1/named.conf.j2
new file mode 100644 (file)
index 0000000..8271d9b
--- /dev/null
@@ -0,0 +1,26 @@
+options {
+       query-source address 10.53.0.1;
+       notify-source 10.53.0.1;
+       transfer-source 10.53.0.1;
+       port @PORT@;
+       pid-file "named.pid";
+       listen-on { 10.53.0.1; };
+       listen-on-v6 { none; };
+       recursion no;
+       notify no;
+       dnssec-validation no;
+};
+
+zone "example" {
+       type primary;
+       file "example.db";
+};
+
+key rndc_key {
+       secret "1234abcd8765";
+       algorithm @DEFAULT_HMAC@;
+};
+
+controls {
+       inet 10.53.0.1 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
+};
diff --git a/bin/tests/system/gluecache/tests_gluecache.py b/bin/tests/system/gluecache/tests_gluecache.py
new file mode 100644 (file)
index 0000000..1e30194
--- /dev/null
@@ -0,0 +1,55 @@
+# 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 dns.flags
+import dns.message
+
+import isctest
+
+
+def test_gluecache_inzone_ns_target(ns1):
+    """Exercise the glue cache path where the NS target is authoritative
+    in-zone data (not glue below a zone cut).
+
+    When sub.example. is delegated to ns.example. and ns.example. lives
+    at the zone apex, qpzone_find returns ISC_R_SUCCESS rather than
+    DNS_R_GLUE in glue_nsdname_cb.  The address records are not treated
+    as glue and are therefore not included in the additional section of
+    the referral.  However, the rdataset returned by qpzone_find is
+    associated but never cleaned up, leaking a vecheader reference.
+
+    Query multiple times to exercise both the cache-miss and cache-hit
+    paths in glue_nsdname_cb, then shut down named and verify no
+    memory was leaked.
+    """
+    for _ in range(3):
+        msg = isctest.query.create("foo.sub.example.", "A")
+        msg.flags &= ~dns.flags.RD
+        res = isctest.query.udp(msg, "10.53.0.1")
+
+        expected = """;ANSWER
+;AUTHORITY
+sub.example. 300 IN NS ns.example.
+;ADDITIONAL
+"""
+        expected_msg = dns.message.from_text(expected)
+
+        isctest.check.noerror(res)
+        isctest.check.rrsets_equal(res.answer, expected_msg.answer)
+        isctest.check.rrsets_equal(res.authority, expected_msg.authority)
+        isctest.check.rrsets_equal(res.additional, expected_msg.additional)
+
+    # Stop the server and check for memory leaks in the shutdown log.
+    # The leaked vecheader reference will show up as outstanding memory
+    # allocations from rdatavec.c in named's memory tracking output.
+    ns1.stop()
+    assert "outstanding memory" not in ns1.log