From 5d793b6ca9cdc80c090e53c8ec9f262568eed9b3 Mon Sep 17 00:00:00 2001 From: Ankur Tyagi Date: Fri, 11 Sep 2026 11:09:08 +1200 Subject: [PATCH] unbound: patch CVE-2026-42923 Details: https://nvd.nist.gov/vuln/detail/cve-2026-42923 Signed-off-by: Ankur Tyagi Signed-off-by: Anuj Mittal --- .../unbound/unbound/CVE-2026-42923.patch | 114 ++++++++++++++++++ .../recipes-support/unbound/unbound_1.24.2.bb | 1 + 2 files changed, 115 insertions(+) create mode 100644 meta-networking/recipes-support/unbound/unbound/CVE-2026-42923.patch diff --git a/meta-networking/recipes-support/unbound/unbound/CVE-2026-42923.patch b/meta-networking/recipes-support/unbound/unbound/CVE-2026-42923.patch new file mode 100644 index 0000000000..da46770183 --- /dev/null +++ b/meta-networking/recipes-support/unbound/unbound/CVE-2026-42923.patch @@ -0,0 +1,114 @@ +From 7a2457c979cdc1f0c1bb1fe68010fdd2f46398f2 Mon Sep 17 00:00:00 2001 +From: "W.C.A. Wijngaards" +Date: Wed, 20 May 2026 10:20:02 +0200 +Subject: [PATCH] - Fix CVE-2026-42923, Degradation of service with unbounded + NSEC3 hash calculations. Thanks to Qifan Zhang, Palo Alto Networks, for + the report. + +(cherry picked from commit c343fff3a4de922835fec7232b90faed658b5371) + +CVE: CVE-2026-42923 +Upstream-Status: Backport [https://github.com/NLnetLabs/unbound/commit/c343fff3a4de922835fec7232b90faed658b5371] + +Dropped changes to the Changelog file. + +Signed-off-by: Ankur Tyagi +--- + validator/val_neg.c | 28 +++++++++++++++++++++++++++- + validator/val_nsec3.c | 5 ----- + validator/val_nsec3.h | 6 ++++++ + 3 files changed, 33 insertions(+), 6 deletions(-) + +diff --git a/validator/val_neg.c b/validator/val_neg.c +index bc3a83aeb..0f2751121 100644 +--- a/validator/val_neg.c ++++ b/validator/val_neg.c +@@ -62,6 +62,13 @@ + #include "sldns/rrdef.h" + #include "sldns/sbuffer.h" + ++/** ++ * The maximum salt length that the negative cache is willing to use. ++ * Larger salt increases the computation time, while recommendations are ++ * for zero salt length for zones. ++ */ ++#define MAX_SALT_LENGTH 64 ++ + int val_neg_data_compare(const void* a, const void* b) + { + struct val_neg_data* x = (struct val_neg_data*)a; +@@ -826,7 +833,11 @@ void neg_insert_data(struct val_neg_cache* neg, + (slen != 0 && zone->nsec3_salt && s + && memcmp(zone->nsec3_salt, s, slen) != 0))) { + +- if(slen > 0) { ++ if(slen > MAX_SALT_LENGTH) { ++ /* RFC 9276 s3.1: operators SHOULD NOT use a salt; large ++ * salts inflate per-hash block count. Decline to cache. */ ++ return; ++ } else if(slen > 0) { + uint8_t* sa = memdup(s, slen); + if(sa) { + free(zone->nsec3_salt); +@@ -1169,6 +1180,15 @@ neg_find_nsec3_ce(struct val_neg_zone* zone, uint8_t* qname, size_t qname_len, + uint8_t hashce[NSEC3_SHA_LEN]; + uint8_t b32[257]; + size_t celen, b32len; ++ int hashmax = MAX_NSEC3_CALCULATIONS; ++ if(qlabs > hashmax) { ++ /* strip leading labels so the walk costs at most ++ * MAX_NSEC3_CALCULATIONS hashes, mirroring val_nsec3.c */ ++ while(qlabs > hashmax) { ++ dname_remove_label(&qname, &qname_len); ++ qlabs--; ++ } ++ } + + *nclen = 0; + while(qlabs > 0) { +@@ -1269,6 +1289,12 @@ neg_nsec3_proof_ds(struct val_neg_zone* zone, uint8_t* qname, size_t qname_len, + if(!zone->nsec3_hash) + return NULL; /* not nsec3 zone */ + ++ if(!topname && qlabs > zone->labs + 1) ++ return NULL; /* iterator caller; opt-out proof would be discarded ++ * at the !topname check below anyway. ++ * The qlabs check allows the exact-match for ++ * the one-label-below-zone case. */ ++ + if(!(data=neg_find_nsec3_ce(zone, qname, qname_len, qlabs, buf, + hashnc, &nclen))) { + return NULL; +diff --git a/validator/val_nsec3.c b/validator/val_nsec3.c +index 92d853825..62effde20 100644 +--- a/validator/val_nsec3.c ++++ b/validator/val_nsec3.c +@@ -59,11 +59,6 @@ + #include "sldns/sbuffer.h" + #include "util/config_file.h" + +-/** +- * Max number of NSEC3 calculations at once, suspend query for later. +- * 8 is low enough and allows for cases where multiple proofs are needed. +- */ +-#define MAX_NSEC3_CALCULATIONS 8 + /** + * When all allowed NSEC3 calculations at once resulted in error treat as + * bogus. NSEC3 hash errors are not cached and this helps breaks loops with +diff --git a/validator/val_nsec3.h b/validator/val_nsec3.h +index f668a270f..a13e92991 100644 +--- a/validator/val_nsec3.h ++++ b/validator/val_nsec3.h +@@ -98,6 +98,12 @@ struct sldns_buffer; + /** The SHA1 hash algorithm for NSEC3 */ + #define NSEC3_HASH_SHA1 0x01 + ++/** ++ * Max number of NSEC3 calculations at once, suspend query for later. ++ * 8 is low enough and allows for cases where multiple proofs are needed. ++ */ ++#define MAX_NSEC3_CALCULATIONS 8 ++ + /** + * Cache table for NSEC3 hashes. + * It keeps a *pointer* to the region its items are allocated. diff --git a/meta-networking/recipes-support/unbound/unbound_1.24.2.bb b/meta-networking/recipes-support/unbound/unbound_1.24.2.bb index a70ae4c9a3..7ed5769c69 100644 --- a/meta-networking/recipes-support/unbound/unbound_1.24.2.bb +++ b/meta-networking/recipes-support/unbound/unbound_1.24.2.bb @@ -19,6 +19,7 @@ SRC_URI = "git://github.com/NLnetLabs/unbound.git;protocol=https;branch=master;t file://CVE-2026-40622.patch \ file://CVE-2026-41292.patch \ file://CVE-2026-42534.patch \ + file://CVE-2026-42923.patch \ " SRCREV = "f6269baa605d31859f28770e01a24e3677e5f82c"