[oe][meta-oe][scarthgap][PATCH] ldns: fix CVE-2026-10846

"Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco)" <[email protected]>
Newsgroups org.openembedded.lists.openembedded-devel
Message-ID <[email protected]>
From: Deepak Rathore <[email protected]>

This patch backports the upstream fixes released in ldns 1.9.2 for
CVE-2026-10846.The upstream commits are referenced in [1], [2], and
[3], and the public CVE advisory is referenced in [4].The individual
backported commit links are also recorded in the embedded patch headers.

[1] https://github.com/NLnetLabs/ldns/commit/a21fb16686bbe3355886905f95e13eab5144d805
[2] https://github.com/NLnetLabs/ldns/commit/9ea51a68d458b43a17ccf4ee98a71325300df524
[3] https://github.com/NLnetLabs/ldns/commit/dc117528dfc60b2dda82d9171b7e9e0b6890da2f
[4] https://www.nlnetlabs.nl/downloads/ldns/CVE-2026-10846.txt

Signed-off-by: Deepak Rathore <[email protected]>
---
 .../ldns/ldns/CVE-2026-10846_p1.patch         | 117 ++++++++++++++++++
 .../ldns/ldns/CVE-2026-10846_p2.patch         | 117 ++++++++++++++++++
 .../ldns/ldns/CVE-2026-10846_p3.patch         |  34 +++++
 meta-oe/recipes-devtools/ldns/ldns_1.8.3.bb   |   6 +-
 4 files changed, 273 insertions(+), 1 deletion(-)
 create mode 100644 meta-oe/recipes-devtools/ldns/ldns/CVE-2026-10846_p1.patch
 create mode 100644 meta-oe/recipes-devtools/ldns/ldns/CVE-2026-10846_p2.patch
 create mode 100644 meta-oe/recipes-devtools/ldns/ldns/CVE-2026-10846_p3.patch

diff --git a/meta-oe/recipes-devtools/ldns/ldns/CVE-2026-10846_p1.patch b/meta-oe/recipes-devtools/ldns/ldns/CVE-2026-10846_p1.patch
new file mode 100644
index 0000000000..4b9d86a2ee
--- /dev/null
+++ b/meta-oe/recipes-devtools/ldns/ldns/CVE-2026-10846_p1.patch
@@ -0,0 +1,117 @@
+From 844fb7e197b646a11dc058c5c7ce0877371bd4d4 Mon Sep 17 00:00:00 2001
+From: "W.C.A. Wijngaards" <[email protected]>
+Date: Fri, 29 May 2026 09:44:27 +0200
+Subject: [PATCH] Fix to check address and port and TXID
+
+CVE: CVE-2026-10846
+Upstream-Status: Backport [https://github.com/NLnetLabs/ldns/commit/a21fb16686bbe3355886905f95e13eab5144d805]
+
+(cherry picked from commit a21fb16686bbe3355886905f95e13eab5144d805)
+Signed-off-by: Deepak Rathore <[email protected]>
+---
+ net.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 64 insertions(+), 1 deletion(-)
+
+diff --git a/net.c b/net.c
+index 57d4dff2..03911637 100644
+--- a/net.c
++++ b/net.c
+@@ -441,6 +441,50 @@ ldns_udp_bgsend2(ldns_buffer *qbin,
+ 	return ldns_udp_bgsend_from(qbin, to, tolen, NULL, 0, timeout);
+ }
+ 
++/** helper sockaddr compare function. returns -1, 0 or 1. */
++static int
++ldns_sockaddr_cmp(const struct sockaddr_storage* addr1, socklen_t len1,
++	const struct sockaddr_storage* addr2, socklen_t len2)
++{
++	struct sockaddr_in* p1_in = (struct sockaddr_in*)addr1;
++	struct sockaddr_in* p2_in = (struct sockaddr_in*)addr2;
++	struct sockaddr_in6* p1_in6 = (struct sockaddr_in6*)addr1;
++	struct sockaddr_in6* p2_in6 = (struct sockaddr_in6*)addr2;
++	if(len1 < len2)
++		return -1;
++	if(len1 > len2)
++		return 1;
++	assert(len1 == len2);
++	if( p1_in->sin_family < p2_in->sin_family)
++		return -1;
++	if( p1_in->sin_family > p2_in->sin_family)
++		return 1;
++	assert( p1_in->sin_family == p2_in->sin_family );
++	/* compare ip4 */
++	if( p1_in->sin_family == AF_INET ) {
++		/* just order it, ntohs not required */
++		if(p1_in->sin_port < p2_in->sin_port)
++			return -1;
++		if(p1_in->sin_port > p2_in->sin_port)
++			return 1;
++		assert(p1_in->sin_port == p2_in->sin_port);
++		return memcmp(&p1_in->sin_addr, &p2_in->sin_addr,
++			sizeof(p1_in->sin_addr));
++	} else if (p1_in6->sin6_family == AF_INET6) {
++		/* just order it, ntohs not required */
++		if(p1_in6->sin6_port < p2_in6->sin6_port)
++			return -1;
++		if(p1_in6->sin6_port > p2_in6->sin6_port)
++			return 1;
++		assert(p1_in6->sin6_port == p2_in6->sin6_port);
++		return memcmp(&p1_in6->sin6_addr, &p2_in6->sin6_addr,
++			sizeof(p1_in6->sin6_addr));
++	} else {
++		/* eek unknown type, perform this comparison for sanity. */
++		return memcmp(addr1, addr2, len1);
++	}
++}
++
+ static ldns_status
+ ldns_udp_send_from(uint8_t **result, ldns_buffer *qbin,
+ 		const struct sockaddr_storage *to  , socklen_t tolen,
+@@ -449,6 +493,8 @@ ldns_udp_send_from(uint8_t **result, ldns_buffer *qbin,
+ {
+ 	int sockfd;
+ 	uint8_t *answer;
++	struct sockaddr_storage reply_addr;
++	socklen_t reply_addr_len;
+ 
+ 	sockfd = ldns_udp_bgsend_from(qbin, to, tolen, from, fromlen, timeout);
+ 
+@@ -467,13 +513,19 @@ ldns_udp_send_from(uint8_t **result, ldns_buffer *qbin,
+          * but returns a 'NETWORK_ERROR' much like a timeout. */
+         ldns_sock_nonblock(sockfd);
+ 
+-	answer = ldns_udp_read_wire(sockfd, answer_size, NULL, NULL);
++	reply_addr_len = sizeof(reply_addr);
++	answer = ldns_udp_read_wire(sockfd, answer_size, &reply_addr,
++		&reply_addr_len);
+ 	close_socket(sockfd);
+ 
+ 	if (!answer) {
+ 		/* oops */
+ 		return LDNS_STATUS_NETWORK_ERR;
+ 	}
++	/* Check that the reply came from the to addr. */
++	if(ldns_sockaddr_cmp(to, tolen, &reply_addr, reply_addr_len) != 0) {
++		return LDNS_STATUS_NETWORK_ERR;
++	}
+ 
+ 	*result = answer;
+ 	return LDNS_STATUS_OK;
+@@ -599,6 +651,17 @@ ldns_send_buffer(ldns_pkt **result, ldns_resolver *r, ldns_buffer *qb, ldns_rdf
+ 			ldns_resolver_set_nameserver_rtt(r, i, LDNS_RESOLV_RTT_INF);
+ 			status = send_status;
+ 		}
++		if(reply_bytes && ldns_buffer_limit(qb) >= 2) {
++			uint16_t txid = ldns_buffer_read_u16_at(qb, 0);
++			if(reply_size < 2 ||
++				ldns_read_uint16(reply_bytes) != txid) {
++				printf("wrong TXID!\n");
++				status = LDNS_STATUS_ERR; /* wrong ID */
++				LDNS_FREE(reply_bytes);
++				reply_bytes = NULL;
++				reply_size = 0;
++			}
++		}
+ 		
+ 		/* obey the fail directive */
+ 		if (!reply_bytes) {
diff --git a/meta-oe/recipes-devtools/ldns/ldns/CVE-2026-10846_p2.patch b/meta-oe/recipes-devtools/ldns/ldns/CVE-2026-10846_p2.patch
new file mode 100644
index 0000000000..f2f9d4b596
--- /dev/null
+++ b/meta-oe/recipes-devtools/ldns/ldns/CVE-2026-10846_p2.patch
@@ -0,0 +1,117 @@
+From 0e291b494fc5e4d3800b27d7016fc92c7aac269e Mon Sep 17 00:00:00 2001
+From: Willem Toorop <[email protected]>
+Date: Tue, 2 Jun 2026 12:19:38 +0200
+Subject: [PATCH] Match question from query in response, and...
+
+... error codes for unmatched ID and for QDCOUNT != 1 in both queries
+and responses
+
+CVE: CVE-2026-10846
+Upstream-Status: Backport [https://github.com/NLnetLabs/ldns/commit/9ea51a68d458b43a17ccf4ee98a71325300df524]
+
+Backport Changes:
+- Omitted upstream test commit 7f6364cd7f595de766a43401bbecf935e042faa5
+  because the ldns recipe does not run the upstream test framework.
+
+(cherry picked from commit 9ea51a68d458b43a17ccf4ee98a71325300df524)
+Signed-off-by: Deepak Rathore <[email protected]>
+---
+ error.c      |  6 ++++++
+ ldns/error.h |  5 ++++-
+ net.c        | 29 ++++++++++++++++++++++++++---
+ 3 files changed, 36 insertions(+), 4 deletions(-)
+
+diff --git a/error.c b/error.c
+index e3fd1211..f046c962 100644
+--- a/error.c
++++ b/error.c
+@@ -184,6 +184,12 @@ ldns_lookup_table ldns_error_str[] = {
+ 	{ LDNS_STATUS_INVALID_SVCPARAM_VALUE,
+ 		"Invalid wireformat of a value "
+ 		"in the ServiceParam rdata field of SVCB or HTTPS RR" },
++	{ LDNS_STATUS_ID_DID_NOT_MATCH,
++		"Response ID did not match the query ID" },
++	{ LDNS_STATUS_QDCOUNT_MUST_BE_ONE,
++		"The query section MUST contain exactly one question" },
++	{ LDNS_STATUS_QUERY_DID_NOT_MATCH,
++		"The question in the response did not match the query" },
+ 	{ 0, NULL }
+ };
+ 
+diff --git a/ldns/error.h b/ldns/error.h
+index 2429b770..5754f5a0 100644
+--- a/ldns/error.h
++++ b/ldns/error.h
+@@ -141,7 +141,10 @@ enum ldns_enum_status {
+ 	LDNS_STATUS_RESERVED_SVCPARAM_KEY,
+ 	LDNS_STATUS_NO_SVCPARAM_VALUE_EXPECTED,
+ 	LDNS_STATUS_SVCPARAM_KEY_MORE_THAN_ONCE,
+-	LDNS_STATUS_INVALID_SVCPARAM_VALUE
++	LDNS_STATUS_INVALID_SVCPARAM_VALUE,
++	LDNS_STATUS_ID_DID_NOT_MATCH,
++	LDNS_STATUS_QDCOUNT_MUST_BE_ONE,
++	LDNS_STATUS_QUERY_DID_NOT_MATCH
+ };
+ typedef enum ldns_enum_status ldns_status;
+ 
+diff --git a/net.c b/net.c
+index 03911637..ab7cf028 100644
+--- a/net.c
++++ b/net.c
+@@ -564,6 +564,10 @@ ldns_send_buffer(ldns_pkt **result, ldns_resolver *r, ldns_buffer *qb, ldns_rdf
+ 
+ 	assert(r != NULL);
+ 
++	/* The query should at least have one question */
++	if(ldns_buffer_limit(qb) < 6 || ldns_buffer_read_u16_at(qb, 4) != 1)
++		return LDNS_STATUS_QDCOUNT_MUST_BE_ONE;
++
+ 	status = LDNS_STATUS_OK;
+ 	rtt = ldns_resolver_rtt(r);
+ 	ns_array = ldns_resolver_nameservers(r);
+@@ -655,8 +659,7 @@ ldns_send_buffer(ldns_pkt **result, ldns_resolver *r, ldns_buffer *qb, ldns_rdf
+ 			uint16_t txid = ldns_buffer_read_u16_at(qb, 0);
+ 			if(reply_size < 2 ||
+ 				ldns_read_uint16(reply_bytes) != txid) {
+-				printf("wrong TXID!\n");
+-				status = LDNS_STATUS_ERR; /* wrong ID */
++				status = LDNS_STATUS_ID_DID_NOT_MATCH;
+ 				LDNS_FREE(reply_bytes);
+ 				reply_bytes = NULL;
+ 				reply_size = 0;
+@@ -671,7 +674,7 @@ ldns_send_buffer(ldns_pkt **result, ldns_resolver *r, ldns_buffer *qb, ldns_rdf
+ 					LDNS_FREE(src);
+ 				}
+ 				LDNS_FREE(ns);
+-				return LDNS_STATUS_ERR;
++				return status ? status : LDNS_STATUS_ERR;
+ 			} else {
+ 				LDNS_FREE(ns);
+ 				continue;
+@@ -733,6 +736,26 @@ ldns_send_buffer(ldns_pkt **result, ldns_resolver *r, ldns_buffer *qb, ldns_rdf
+ #endif /* HAVE_SSL */
+ 
+ 	LDNS_FREE(reply_bytes);
++	if (reply) {
++		ldns_pkt *query = NULL;
++
++		if(ldns_pkt_qdcount(reply) != 1) {
++			status = LDNS_STATUS_QDCOUNT_MUST_BE_ONE;
++			ldns_pkt_free(reply);
++			reply = NULL;
++
++		} else if(ldns_wire2pkt(&query
++		                , ldns_buffer_begin(qb)
++		                , ldns_buffer_position(qb)) != LDNS_STATUS_OK
++		|| ldns_pkt_qdcount(query) != 1
++		|| ldns_rr_compare(ldns_rr_list_rr(ldns_pkt_question(query),0)
++		                  ,ldns_rr_list_rr(ldns_pkt_question(reply),0))){
++			status = LDNS_STATUS_QUERY_DID_NOT_MATCH;
++			ldns_pkt_free(reply);
++			reply = NULL;
++		}
++		ldns_pkt_free(query);
++	}
+ 	if (result) {
+ 		*result = reply;
+ 	}
diff --git a/meta-oe/recipes-devtools/ldns/ldns/CVE-2026-10846_p3.patch b/meta-oe/recipes-devtools/ldns/ldns/CVE-2026-10846_p3.patch
new file mode 100644
index 0000000000..f0f0de8b71
--- /dev/null
+++ b/meta-oe/recipes-devtools/ldns/ldns/CVE-2026-10846_p3.patch
@@ -0,0 +1,34 @@
+From b2cae7389bc43613fdd21bed1f9d41b3870c5545 Mon Sep 17 00:00:00 2001
+From: Willem Toorop <[email protected]>
+Date: Tue, 2 Jun 2026 12:42:38 +0200
+Subject: [PATCH] Issues from clang analysis
+
+CVE: CVE-2026-10846
+Upstream-Status: Backport [https://github.com/NLnetLabs/ldns/commit/dc117528dfc60b2dda82d9171b7e9e0b6890da2f]
+
+(cherry picked from commit dc117528dfc60b2dda82d9171b7e9e0b6890da2f)
+Signed-off-by: Deepak Rathore <[email protected]>
+---
+ net.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net.c b/net.c
+index ab7cf028..215c0cac 100644
+--- a/net.c
++++ b/net.c
+@@ -514,6 +514,7 @@ ldns_udp_send_from(uint8_t **result, ldns_buffer *qbin,
+         ldns_sock_nonblock(sockfd);
+ 
+ 	reply_addr_len = sizeof(reply_addr);
++	memset(&reply_addr, 0, reply_addr_len);
+ 	answer = ldns_udp_read_wire(sockfd, answer_size, &reply_addr,
+ 		&reply_addr_len);
+ 	close_socket(sockfd);
+@@ -524,6 +525,7 @@ ldns_udp_send_from(uint8_t **result, ldns_buffer *qbin,
+ 	}
+ 	/* Check that the reply came from the to addr. */
+ 	if(ldns_sockaddr_cmp(to, tolen, &reply_addr, reply_addr_len) != 0) {
++		free(answer);
+ 		return LDNS_STATUS_NETWORK_ERR;
+ 	}
+ 
diff --git a/meta-oe/recipes-devtools/ldns/ldns_1.8.3.bb b/meta-oe/recipes-devtools/ldns/ldns_1.8.3.bb
index 80e5571954..75d02ad673 100644
--- a/meta-oe/recipes-devtools/ldns/ldns_1.8.3.bb
+++ b/meta-oe/recipes-devtools/ldns/ldns_1.8.3.bb
@@ -3,7 +3,11 @@ HOMEPAGE = "https://nlnetlabs.nl/ldns"
 LICENSE = "BSD-3-Clause"
 LIC_FILES_CHKSUM = "file://LICENSE;md5=34330f15b2b4abbbaaa7623f79a6a019"
 
-SRC_URI = "https://www.nlnetlabs.nl/downloads/ldns/ldns-${PV}.tar.gz"
+SRC_URI = "https://www.nlnetlabs.nl/downloads/ldns/ldns-${PV}.tar.gz \
+           file://CVE-2026-10846_p1.patch \
+           file://CVE-2026-10846_p2.patch \
+           file://CVE-2026-10846_p3.patch \
+           "
 SRC_URI[sha256sum] = "c3f72dd1036b2907e3a56e6acf9dfb2e551256b3c1bbd9787942deeeb70e7860"
 
 DEPENDS = "openssl"
-- 
2.35.6
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.