public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
* [rpms/bind] f45: Cache poisoning via label count discrepancy, RRSIG, wildcards (CVE-2026-11721)
@ 2026-08-26  8:34 
  0 siblings, 0 replies; only message in thread
From:  @ 2026-08-26  8:34 UTC (permalink / raw)
  To: git-commits

            A new commit has been pushed.

            Repo   : rpms/bind
            Branch : f45
            Commit : 238ad5761b1f91463a9845296d13483cd08d7593
            Author : Petr Menšík <pemensik@redhat.com>
            Date   : 2026-08-25T12:46:33+02:00
            Stats  : +414/-0 in 3 file(s)
            URL    : https://src.fedoraproject.org/rpms/bind/c/238ad5761b1f91463a9845296d13483cd08d7593?branch=f45

            Log:
            Cache poisoning via label count discrepancy, RRSIG, wildcards (CVE-2026-11721)

[9.18] [CVE-2026-11721] sec: usr: Invalid signed wildcard records were being accepted

Signed wildcard responses in which the Labels field in the `RRSIG` record was less than the number of labels in the Signer Name field were being incorrectly accepted. This in turn broke `synth-from-dnssec`, which depends on such records being correctly validated. This has been fixed.

ISC thanks Qifan Zhang of Palo Alto Networks for bringing this issue to our attention.

Closes https://gitlab.isc.org/isc-projects/bind9/-/issues/5871

---
diff --git a/bind-9.18-CVE-2026-11721-test.patch b/bind-9.18-CVE-2026-11721-test.patch
new file mode 100644
index 0000000..7c54994
--- /dev/null
+++ b/bind-9.18-CVE-2026-11721-test.patch
@@ -0,0 +1,144 @@
+From b08e0876639ab9f3dae3813202861fd1098f2611 Mon Sep 17 00:00:00 2001
+From: Mark Andrews <marka@isc.org>
+Date: Tue, 14 Apr 2026 13:46:22 +1000
+Subject: [PATCH] Test RRSIG record parsing
+
+In particular test that labels and signer fields are consistent.
+
+(cherry picked from commit 5a95e64731afe63d348d272cc4d3b2f9847150c2)
+(cherry picked from commit 19e496ca260b6a756ae1378e8ebcbdb666b7d9ed)
+---
+ tests/dns/rdata_test.c | 110 +++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 110 insertions(+)
+
+diff --git a/tests/dns/rdata_test.c b/tests/dns/rdata_test.c
+index 7f0df6e046..c704d98ed1 100644
+--- a/tests/dns/rdata_test.c
++++ b/tests/dns/rdata_test.c
+@@ -2504,6 +2504,115 @@ ISC_RUN_TEST_IMPL(rkey) {
+ 		    dns_rdatatype_rkey, sizeof(dns_rdata_rkey_t));
+ }
+ 
++ISC_RUN_TEST_IMPL(rrsig) {
++	text_ok_t text_ok[] = {
++		TEXT_VALID("SOA 8 0 86400 20260426170000 20260413160000 54393 "
++			   ". "
++			   "tFbcoVP8MnpecUquJ/aj+XeNgV7ts9GSHVkXaXRJrJ/"
++			   "TEkOZApVG0F6E "
++			   "9sYpxGk2ItweLL43ujioGj0HWwZDRR+vbur+O/"
++			   "dIdheiig1VvU+9HXLi "
++			   "QOViY9Kc64ixdyJhYCC5K+bO1qsHxd+"
++			   "KJXOaxyHbqchYkDFy4PL6qftE "
++			   "VaLkueRgjXgOsq/"
++			   "NxvCXDgAa5xy0+3Sl0myxIs8rJ5KeXfJQFe7qxgaw "
++			   "VjJsJTKw8neOTw2rQfLaigWu2LIWw+"
++			   "IyVrLjZJdLqGkiLBGd1w4X3U12 "
++			   "fFxoY3eqzNgBEtduoGKPZ/"
++			   "NpP9cuKJORJ18283aV8hR4WO91VR0q1zcM jLwqUg=="),
++		/* labels too short for signer */
++		TEXT_INVALID("SOA 8 0 86400 20260426170000 20260413160000 "
++			     "54393 example. "
++			     "tFbcoVP8MnpecUquJ/aj+XeNgV7ts9GSHVkXaXRJrJ/"
++			     "TEkOZApVG0F6E "
++			     "9sYpxGk2ItweLL43ujioGj0HWwZDRR+vbur+O/"
++			     "dIdheiig1VvU+9HXLi "
++			     "QOViY9Kc64ixdyJhYCC5K+bO1qsHxd+"
++			     "KJXOaxyHbqchYkDFy4PL6qftE "
++			     "VaLkueRgjXgOsq/"
++			     "NxvCXDgAa5xy0+3Sl0myxIs8rJ5KeXfJQFe7qxgaw "
++			     "VjJsJTKw8neOTw2rQfLaigWu2LIWw+"
++			     "IyVrLjZJdLqGkiLBGd1w4X3U12 "
++			     "fFxoY3eqzNgBEtduoGKPZ/"
++			     "NpP9cuKJORJ18283aV8hR4WO91VR0q1zcM jLwqUg=="),
++		/*
++		 * Sentinel.
++		 */
++		TEXT_SENTINEL()
++	};
++	wire_ok_t wire_ok[] = {
++		WIRE_VALID(0x00, 0x06, 0x08, 0x00, 0x00, 0x01, 0x51, 0x80, 0x69,
++			   0xee, 0x44, 0x90, 0x69, 0xdd, 0x13, 0x00, 0xd4, 0x79,
++			   0x00, 0xb4, 0x56, 0xdc, 0xa1, 0x53, 0xfc, 0x32, 0x7a,
++			   0x5e, 0x71, 0x4a, 0xae, 0x27, 0xf6, 0xa3, 0xf9, 0x77,
++			   0x8d, 0x81, 0x5e, 0xed, 0xb3, 0xd1, 0x92, 0x1d, 0x59,
++			   0x17, 0x69, 0x74, 0x49, 0xac, 0x9f, 0xd3, 0x12, 0x43,
++			   0x99, 0x02, 0x95, 0x46, 0xd0, 0x5e, 0x84, 0xf6, 0xc6,
++			   0x29, 0xc4, 0x69, 0x36, 0x22, 0xdc, 0x1e, 0x2c, 0xbe,
++			   0x37, 0xba, 0x38, 0xa8, 0x1a, 0x3d, 0x07, 0x5b, 0x06,
++			   0x43, 0x45, 0x1f, 0xaf, 0x6e, 0xea, 0xfe, 0x3b, 0xf7,
++			   0x48, 0x76, 0x17, 0xa2, 0x8a, 0x0d, 0x55, 0xbd, 0x4f,
++			   0xbd, 0x1d, 0x72, 0xe2, 0x40, 0xe5, 0x62, 0x63, 0xd2,
++			   0x9c, 0xeb, 0x88, 0xb1, 0x77, 0x22, 0x61, 0x60, 0x20,
++			   0xb9, 0x2b, 0xe6, 0xce, 0xd6, 0xab, 0x07, 0xc5, 0xdf,
++			   0x8a, 0x25, 0x73, 0x9a, 0xc7, 0x21, 0xdb, 0xa9, 0xc8,
++			   0x58, 0x90, 0x31, 0x72, 0xe0, 0xf2, 0xfa, 0xa9, 0xfb,
++			   0x44, 0x55, 0xa2, 0xe4, 0xb9, 0xe4, 0x60, 0x8d, 0x78,
++			   0x0e, 0xb2, 0xaf, 0xcd, 0xc6, 0xf0, 0x97, 0x0e, 0x00,
++			   0x1a, 0xe7, 0x1c, 0xb4, 0xfb, 0x74, 0xa5, 0xd2, 0x6c,
++			   0xb1, 0x22, 0xcf, 0x2b, 0x27, 0x92, 0x9e, 0x5d, 0xf2,
++			   0x50, 0x15, 0xee, 0xea, 0xc6, 0x06, 0xb0, 0x56, 0x32,
++			   0x6c, 0x25, 0x32, 0xb0, 0xf2, 0x77, 0x8e, 0x4f, 0x0d,
++			   0xab, 0x41, 0xf2, 0xda, 0x8a, 0x05, 0xae, 0xd8, 0xb2,
++			   0x16, 0xc3, 0xe2, 0x32, 0x56, 0xb2, 0xe3, 0x64, 0x97,
++			   0x4b, 0xa8, 0x69, 0x22, 0x2c, 0x11, 0x9d, 0xd7, 0x0e,
++			   0x17, 0xdd, 0x4d, 0x76, 0x7c, 0x5c, 0x68, 0x63, 0x77,
++			   0xaa, 0xcc, 0xd8, 0x01, 0x12, 0xd7, 0x6e, 0xa0, 0x62,
++			   0x8f, 0x67, 0xf3, 0x69, 0x3f, 0xd7, 0x2e, 0x28, 0x93,
++			   0x91, 0x27, 0x5f, 0x36, 0xf3, 0x76, 0x95, 0xf2, 0x14,
++			   0x78, 0x58, 0xef, 0x75, 0x55, 0x1d, 0x2a, 0xd7, 0x37,
++			   0x0c, 0x8c, 0xbc, 0x2a, 0x52),
++		/* labels too short for signer */
++		WIRE_INVALID(
++			0x00, 0x06, 0x08, 0x00, 0x00, 0x01, 0x51, 0x80, 0x69,
++			0xee, 0x44, 0x90, 0x69, 0xdd, 0x13, 0x00, 0xd4, 0x79,
++			0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x00,
++			0xb4, 0x56, 0xdc, 0xa1, 0x53, 0xfc, 0x32, 0x7a, 0x5e,
++			0x71, 0x4a, 0xae, 0x27, 0xf6, 0xa3, 0xf9, 0x77, 0x8d,
++			0x81, 0x5e, 0xed, 0xb3, 0xd1, 0x92, 0x1d, 0x59, 0x17,
++			0x69, 0x74, 0x49, 0xac, 0x9f, 0xd3, 0x12, 0x43, 0x99,
++			0x02, 0x95, 0x46, 0xd0, 0x5e, 0x84, 0xf6, 0xc6, 0x29,
++			0xc4, 0x69, 0x36, 0x22, 0xdc, 0x1e, 0x2c, 0xbe, 0x37,
++			0xba, 0x38, 0xa8, 0x1a, 0x3d, 0x07, 0x5b, 0x06, 0x43,
++			0x45, 0x1f, 0xaf, 0x6e, 0xea, 0xfe, 0x3b, 0xf7, 0x48,
++			0x76, 0x17, 0xa2, 0x8a, 0x0d, 0x55, 0xbd, 0x4f, 0xbd,
++			0x1d, 0x72, 0xe2, 0x40, 0xe5, 0x62, 0x63, 0xd2, 0x9c,
++			0xeb, 0x88, 0xb1, 0x77, 0x22, 0x61, 0x60, 0x20, 0xb9,
++			0x2b, 0xe6, 0xce, 0xd6, 0xab, 0x07, 0xc5, 0xdf, 0x8a,
++			0x25, 0x73, 0x9a, 0xc7, 0x21, 0xdb, 0xa9, 0xc8, 0x58,
++			0x90, 0x31, 0x72, 0xe0, 0xf2, 0xfa, 0xa9, 0xfb, 0x44,
++			0x55, 0xa2, 0xe4, 0xb9, 0xe4, 0x60, 0x8d, 0x78, 0x0e,
++			0xb2, 0xaf, 0xcd, 0xc6, 0xf0, 0x97, 0x0e, 0x00, 0x1a,
++			0xe7, 0x1c, 0xb4, 0xfb, 0x74, 0xa5, 0xd2, 0x6c, 0xb1,
++			0x22, 0xcf, 0x2b, 0x27, 0x92, 0x9e, 0x5d, 0xf2, 0x50,
++			0x15, 0xee, 0xea, 0xc6, 0x06, 0xb0, 0x56, 0x32, 0x6c,
++			0x25, 0x32, 0xb0, 0xf2, 0x77, 0x8e, 0x4f, 0x0d, 0xab,
++			0x41, 0xf2, 0xda, 0x8a, 0x05, 0xae, 0xd8, 0xb2, 0x16,
++			0xc3, 0xe2, 0x32, 0x56, 0xb2, 0xe3, 0x64, 0x97, 0x4b,
++			0xa8, 0x69, 0x22, 0x2c, 0x11, 0x9d, 0xd7, 0x0e, 0x17,
++			0xdd, 0x4d, 0x76, 0x7c, 0x5c, 0x68, 0x63, 0x77, 0xaa,
++			0xcc, 0xd8, 0x01, 0x12, 0xd7, 0x6e, 0xa0, 0x62, 0x8f,
++			0x67, 0xf3, 0x69, 0x3f, 0xd7, 0x2e, 0x28, 0x93, 0x91,
++			0x27, 0x5f, 0x36, 0xf3, 0x76, 0x95, 0xf2, 0x14, 0x78,
++			0x58, 0xef, 0x75, 0x55, 0x1d, 0x2a, 0xd7, 0x37, 0x0c,
++			0x8c, 0xbc, 0x2a, 0x52),
++
++		WIRE_SENTINEL()
++	};
++	check_rdata(text_ok, wire_ok, NULL, false, dns_rdataclass_in,
++		    dns_rdatatype_rrsig, sizeof(dns_rdata_rrsig_t));
++}
++
+ ISC_RUN_TEST_IMPL(resinfo) {
+ 	text_ok_t text_ok[] = {
+ 		TEXT_VALID_CHANGED("qnamemin exterr=15,16,17 "
+@@ -3357,6 +3466,7 @@ ISC_TEST_ENTRY(nsec3)
+ ISC_TEST_ENTRY(nxt)
+ ISC_TEST_ENTRY(resinfo)
+ ISC_TEST_ENTRY(rkey)
++ISC_TEST_ENTRY(rrsig)
+ ISC_TEST_ENTRY(sshfp)
+ ISC_TEST_ENTRY(wallet)
+ ISC_TEST_ENTRY(wks)
+-- 
+2.55.0
+

diff --git a/bind-9.18-CVE-2026-11721.patch b/bind-9.18-CVE-2026-11721.patch
new file mode 100644
index 0000000..d59130b
--- /dev/null
+++ b/bind-9.18-CVE-2026-11721.patch
@@ -0,0 +1,267 @@
+From 7a8a1f74c742e98fb5e105b013e7c2bd7af4a76c Mon Sep 17 00:00:00 2001
+From: Mark Andrews <marka@isc.org>
+Date: Tue, 14 Apr 2026 15:14:06 +1000
+Subject: [PATCH] Don't sign out of zone records in dnssec-signzone
+
+dnssec-signzone was signing extraneous records that were not within
+the namespace of the zone.  This no longer occurs.
+
+(cherry picked from commit e45c9af7051421fd370f20ba8325199c606223fd)
+
+Don't sign out of zone records in dnssec-signzone
+
+dnssec-signzone was signing extraneous records that were not within
+the namespace of the zone.  This no longer occurs.
+
+(cherry picked from commit e45c9af7051421fd370f20ba8325199c606223fd)
+(cherry picked from commit 1a4986e2533f87e80eb21da3f06708d335aff1e2)
+
+Invalid signed wildcard records were being accepted
+
+An RRSIG whose Labels field indicates fewer labels than its signer
+name requires was being accepted.  When such a record covers a
+wildcard, the validator reconstructs a wildcard owner name above the
+signer's zone and caches it as secure.  RFC 8198 cache synthesis
+(synth-from-dnssec) then serves that forged wildcard for unrelated
+names, poisoning the cache.
+
+These records are now rejected, both when an RRSIG is parsed and when
+its signature is verified.
+
+(cherry picked from commit 084ca5ee10515e461d46b63df9660b8394bc7de9)
+(cherry picked from commit 15089066b15f826d7487c3d160b5872820f84b83)
+---
+ bin/dnssec/dnssec-signzone.c     |  5 ++++
+ lib/dns/dnssec.c                 | 43 +++++++++++++++++++++++---------
+ lib/dns/rdata/generic/rrsig_46.c | 37 ++++++++++++++++++++-------
+ 3 files changed, 64 insertions(+), 21 deletions(-)
+
+diff --git a/bin/dnssec/dnssec-signzone.c b/bin/dnssec/dnssec-signzone.c
+index 73855e6284..9e3a48a592 100644
+--- a/bin/dnssec/dnssec-signzone.c
++++ b/bin/dnssec/dnssec-signzone.c
+@@ -1643,6 +1643,11 @@ assignwork(isc_task_t *task, isc_task_t *worker) {
+ 			dns_db_detachnode(gdb, &node);
+ 			goto next;
+ 		}
++		if (!dns_name_issubdomain(name, gorigin)) {
++			dumpnode(name, node);
++			dns_db_detachnode(gdb, &node);
++			goto next;
++		}
+ 		/*
+ 		 * Sort the zone data from the glue and out-of-zone data.
+ 		 * For NSEC zones nodes with zone data have NSEC records.
+diff --git a/lib/dns/dnssec.c b/lib/dns/dnssec.c
+index c7e922437c..b12529b5d5 100644
+--- a/lib/dns/dnssec.c
++++ b/lib/dns/dnssec.c
+@@ -130,11 +130,11 @@ dns_dnssec_keyfromrdata(const dns_name_t *name, const dns_rdata_t *rdata,
+ 	isc_buffer_t b;
+ 	isc_region_t r;
+ 
+-	INSIST(name != NULL);
+-	INSIST(rdata != NULL);
+-	INSIST(mctx != NULL);
+-	INSIST(key != NULL);
+-	INSIST(*key == NULL);
++	REQUIRE(name != NULL);
++	REQUIRE(rdata != NULL);
++	REQUIRE(mctx != NULL);
++	REQUIRE(key != NULL);
++	REQUIRE(*key == NULL);
+ 	REQUIRE(rdata->type == dns_rdatatype_key ||
+ 		rdata->type == dns_rdatatype_dnskey);
+ 
+@@ -187,12 +187,14 @@ dns_dnssec_sign(const dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
+ 	isc_result_t ret;
+ 	isc_buffer_t *databuf = NULL;
+ 	char data[256 + 8];
++	unsigned int labels;
+ 	unsigned int sigsize;
+ 	dns_fixedname_t fnewname;
+ 	dns_fixedname_t fsigner;
+ 
+ 	REQUIRE(name != NULL);
+-	REQUIRE(dns_name_countlabels(name) <= 255);
++	labels = dns_name_countlabels(name);
++	REQUIRE(labels <= 255 && labels > 0);
+ 	REQUIRE(set != NULL);
+ 	REQUIRE(key != NULL);
+ 	REQUIRE(inception != NULL);
+@@ -221,7 +223,7 @@ dns_dnssec_sign(const dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
+ 
+ 	sig.covered = set->type;
+ 	sig.algorithm = dst_key_alg(key);
+-	sig.labels = dns_name_countlabels(name) - 1;
++	sig.labels = labels - 1;
+ 	if (dns_name_iswildcard(name)) {
+ 		sig.labels--;
+ 	}
+@@ -365,10 +367,13 @@ dns_dnssec_verify(const dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
+ 	isc_result_t ret;
+ 	unsigned char data[300];
+ 	dst_context_t *ctx = NULL;
+-	int labels = 0;
++	unsigned int labels;
++	unsigned int siglabels;
+ 	bool downcase = false;
+ 
+ 	REQUIRE(name != NULL);
++	labels = dns_name_countlabels(name);
++	REQUIRE(labels > 0);
+ 	REQUIRE(set != NULL);
+ 	REQUIRE(key != NULL);
+ 	REQUIRE(mctx != NULL);
+@@ -383,6 +388,21 @@ dns_dnssec_verify(const dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
+ 		return DNS_R_SIGINVALID;
+ 	}
+ 
++	/*
++	 * The RRSIG labels field can't indicate fewer labels than the
++	 * signer.  Also the labels shouldn't be greater than that of
++	 * the owner name.
++	 *
++	 * sig.labels doesn't include the root label, so add 1 to account
++	 * for it.
++	 */
++	siglabels = sig.labels + 1;
++	if (siglabels < dns_name_countlabels(&sig.signer) || siglabels > labels)
++	{
++		inc_stat(dns_dnssecstats_fail);
++		return DNS_R_SIGINVALID;
++	}
++
+ 	if (isc_serial_lt(sig.timeexpire, sig.timesigned)) {
+ 		inc_stat(dns_dnssecstats_fail);
+ 		return DNS_R_SIGINVALID;
+@@ -449,10 +469,9 @@ again:
+ 	 * If the name is an expanded wildcard, use the wildcard name.
+ 	 */
+ 	dns_fixedname_init(&fnewname);
+-	labels = dns_name_countlabels(name) - 1;
+ 	RUNTIME_CHECK(dns_name_downcase(name, dns_fixedname_name(&fnewname),
+ 					NULL) == ISC_R_SUCCESS);
+-	if (labels - sig.labels > 0) {
++	if (labels > siglabels) {
+ 		dns_name_split(dns_fixedname_name(&fnewname), sig.labels + 1,
+ 			       NULL, dns_fixedname_name(&fnewname));
+ 	}
+@@ -463,7 +482,7 @@ again:
+ 	 * Create an envelope for each rdata: <name|type|class|ttl>.
+ 	 */
+ 	isc_buffer_init(&envbuf, data, sizeof(data));
+-	if (labels - sig.labels > 0) {
++	if (labels > siglabels) {
+ 		isc_buffer_putuint8(&envbuf, 1);
+ 		isc_buffer_putuint8(&envbuf, '*');
+ 		memmove(data + 2, r.base, r.length);
+@@ -559,7 +578,7 @@ cleanup_struct:
+ 		inc_stat(dns_dnssecstats_fail);
+ 	}
+ 
+-	if (ret == ISC_R_SUCCESS && labels - sig.labels > 0) {
++	if (ret == ISC_R_SUCCESS && labels > siglabels) {
+ 		if (wild != NULL) {
+ 			RUNTIME_CHECK(dns_name_concatenate(
+ 					      dns_wildcardname,
+diff --git a/lib/dns/rdata/generic/rrsig_46.c b/lib/dns/rdata/generic/rrsig_46.c
+index 10bc039e93..4cf4259c2b 100644
+--- a/lib/dns/rdata/generic/rrsig_46.c
++++ b/lib/dns/rdata/generic/rrsig_46.c
+@@ -23,12 +23,12 @@
+ static isc_result_t
+ fromtext_rrsig(ARGS_FROMTEXT) {
+ 	isc_token_t token;
+-	unsigned char c;
++	unsigned char alg, labels;
+ 	long i;
+ 	dns_rdatatype_t covered;
+-	char *e;
++	char *e = NULL;
+ 	isc_result_t result;
+-	dns_name_t name;
++	dns_name_t signer;
+ 	isc_buffer_t buffer;
+ 	uint32_t time_signed, time_expire;
+ 
+@@ -61,8 +61,8 @@ fromtext_rrsig(ARGS_FROMTEXT) {
+ 	 */
+ 	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
+ 				      false));
+-	RETTOK(dns_secalg_fromtext(&c, &token.value.as_textregion));
+-	RETERR(mem_tobuffer(target, &c, 1));
++	RETTOK(dns_secalg_fromtext(&alg, &token.value.as_textregion));
++	RETERR(mem_tobuffer(target, &alg, 1));
+ 
+ 	/*
+ 	 * Labels.
+@@ -72,8 +72,8 @@ fromtext_rrsig(ARGS_FROMTEXT) {
+ 	if (token.value.as_ulong > 0xffU) {
+ 		RETTOK(ISC_R_RANGE);
+ 	}
+-	c = (unsigned char)token.value.as_ulong;
+-	RETERR(mem_tobuffer(target, &c, 1));
++	labels = (unsigned char)token.value.as_ulong;
++	RETERR(mem_tobuffer(target, &labels, 1));
+ 
+ 	/*
+ 	 * Original ttl.
+@@ -144,12 +144,20 @@ fromtext_rrsig(ARGS_FROMTEXT) {
+ 	 */
+ 	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
+ 				      false));
+-	dns_name_init(&name, NULL);
++	dns_name_init(&signer, NULL);
+ 	buffer_fromregion(&buffer, &token.value.as_region);
+ 	if (origin == NULL) {
+ 		origin = dns_rootname;
+ 	}
+-	RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target));
++	RETTOK(dns_name_fromtext(&signer, &buffer, origin, options, target));
++
++	/*
++	 * (RRSIG labels doesn't include the root label, so add one
++	 * to normalize it before checking against the signer.)
++	 */
++	if ((unsigned int)(labels + 1) < dns_name_countlabels(&signer)) {
++		RETTOK(ISC_R_RANGE);
++	}
+ 
+ 	/*
+ 	 * Sig.
+@@ -278,6 +286,7 @@ static isc_result_t
+ fromwire_rrsig(ARGS_FROMWIRE) {
+ 	isc_region_t sr;
+ 	dns_name_t name;
++	unsigned char labels;
+ 
+ 	REQUIRE(type == dns_rdatatype_rrsig);
+ 
+@@ -300,6 +309,8 @@ fromwire_rrsig(ARGS_FROMWIRE) {
+ 		return ISC_R_UNEXPECTEDEND;
+ 	}
+ 
++	labels = sr.base[3];
++
+ 	isc_buffer_forward(source, 18);
+ 	RETERR(mem_tobuffer(target, sr.base, 18));
+ 
+@@ -309,6 +320,14 @@ fromwire_rrsig(ARGS_FROMWIRE) {
+ 	dns_name_init(&name, NULL);
+ 	RETERR(dns_name_fromwire(&name, source, dctx, options, target));
+ 
++	/*
++	 * (RRSIG labels doesn't include the root label, so add one
++	 * to normalize it before checking against the signer.)
++	 */
++	if ((unsigned int)(labels + 1) < dns_name_countlabels(&name)) {
++		RETERR(DNS_R_FORMERR);
++	}
++
+ 	/*
+ 	 * Sig.
+ 	 */
+-- 
+2.55.0
+

diff --git a/bind.spec b/bind.spec
index dce493d..97c1f00 100644
--- a/bind.spec
+++ b/bind.spec
@@ -173,6 +173,9 @@ Patch41: bind-9.18-CVE-2026-12617.patch
 Patch42: bind-9.18-CVE-2026-12617-test.patch
 # https://gitlab.isc.org/isc-projects/bind9/commit/14d23a4955c62efe974266a8e96a8c5d7caad040
 Patch43: bind-9.18-CVE-2026-11622.patch
+# https://gitlab.isc.org/isc-projects/bind9/commit/58812f64bf14b3930f5bb90a2d0e1f59bc8260b4
+Patch44: bind-9.18-CVE-2026-11721.patch
+Patch45: bind-9.18-CVE-2026-11721-test.patch
 
 %{?systemd_ordering}
 # https://fedoraproject.org/wiki/Changes/RPMSuportForSystemdSysusers

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2026-08-26  8:34 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-08-26  8:34 [rpms/bind] f45: Cache poisoning via label count discrepancy, RRSIG, wildcards (CVE-2026-11721) 

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox