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

-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#128244): 
https://lists.openembedded.org/g/openembedded-devel/message/128244
Mute This Topic: https://lists.openembedded.org/mt/120311035/21656
Group Owner: [email protected]
Unsubscribe: https://lists.openembedded.org/g/openembedded-devel/unsub 
[[email protected]]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to