mirror of
https://github.com/openembedded/meta-openembedded.git
synced 2026-09-23 11:21:11 +00:00
unbound: patch CVE-2026-46582
Details: https://nvd.nist.gov/vuln/detail/cve-2026-46582 Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com> Signed-off-by: Anuj Mittal <anuj.mittal@oss.qualcomm.com>
This commit is contained in:
@@ -0,0 +1,151 @@
|
||||
From 97245ce2852162fbf19cc23b016ee73fe2aec63c Mon Sep 17 00:00:00 2001
|
||||
From: "W.C.A. Wijngaards" <wouter@nlnetlabs.nl>
|
||||
Date: Wed, 22 Jul 2026 10:07:52 +0200
|
||||
Subject: [PATCH] - Fix CVE-2026-46582, A wildcard replay, as another piece of
|
||||
data, triggers poisoning in the serve expired reply path. Thanks to Qifan
|
||||
Zhang, Palo Alto Networks, for the report.
|
||||
|
||||
(cherry picked from commit fea0ff550bb6193417c9b17ffff409eb6736f90d)
|
||||
|
||||
CVE: CVE-2026-46582
|
||||
Upstream-Status: Backport [https://github.com/NLnetLabs/unbound/commit/fea0ff550bb6193417c9b17ffff409eb6736f90d]
|
||||
|
||||
Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com>
|
||||
---
|
||||
validator/val_utils.c | 15 ++++++++++++---
|
||||
validator/validator.c | 31 ++++++++++++++++++++++++++++++-
|
||||
2 files changed, 42 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/validator/val_utils.c b/validator/val_utils.c
|
||||
index 4495695ac..87c5a034a 100644
|
||||
--- a/validator/val_utils.c
|
||||
+++ b/validator/val_utils.c
|
||||
@@ -439,10 +439,15 @@ val_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
* only improves security status
|
||||
* and bogus is set only once, even if we rechecked the status */
|
||||
if(sec > d->security) {
|
||||
+ int wc_expanded = 0;
|
||||
d->security = sec;
|
||||
- if(sec == sec_status_secure)
|
||||
+ if(sec == sec_status_secure) {
|
||||
+ uint8_t* wc = NULL;
|
||||
+ size_t wclen = 0;
|
||||
d->trust = rrset_trust_validated;
|
||||
- else if(sec == sec_status_bogus) {
|
||||
+ if(val_rrset_wildcard(rrset, &wc, &wclen) && wc)
|
||||
+ wc_expanded = 1;
|
||||
+ } else if(sec == sec_status_bogus) {
|
||||
size_t i;
|
||||
/* update ttl for rrset to fixed value. */
|
||||
d->ttl = ve->bogus_ttl;
|
||||
@@ -455,7 +460,11 @@ val_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
lock_basic_unlock(&ve->bogus_lock);
|
||||
}
|
||||
/* if status updated - store in cache for reuse */
|
||||
- rrset_update_sec_status(env->rrset_cache, rrset, *env->now);
|
||||
+ /* For a wildcard rrset, that is secure, do not store this
|
||||
+ * into the cache, because it changes proofs around the
|
||||
+ * item. */
|
||||
+ if(!wc_expanded)
|
||||
+ rrset_update_sec_status(env->rrset_cache, rrset, *env->now);
|
||||
}
|
||||
|
||||
return sec;
|
||||
diff --git a/validator/validator.c b/validator/validator.c
|
||||
index 5817fc808..68c4bf643 100644
|
||||
--- a/validator/validator.c
|
||||
+++ b/validator/validator.c
|
||||
@@ -1013,6 +1013,9 @@ validate_positive_response(struct module_env* env, struct val_env* ve,
|
||||
size_t wl;
|
||||
int wc_cached = 0;
|
||||
int wc_NSEC_ok = 0;
|
||||
+ /* This is used to update the RRset cache, with the combination
|
||||
+ * of the dname expansion and this wildcard, for security status. */
|
||||
+ struct ub_packed_rrset_key* wc_rrset = NULL;
|
||||
int nsec3s_seen = 0;
|
||||
size_t i;
|
||||
struct ub_packed_rrset_key* s;
|
||||
@@ -1031,6 +1034,9 @@ validate_positive_response(struct module_env* env, struct val_env* ve,
|
||||
ntohs(s->rk.type), ntohs(s->rk.rrset_class));
|
||||
chase_reply->security = sec_status_bogus;
|
||||
update_reason_bogus(chase_reply, LDNS_EDE_DNSSEC_BOGUS);
|
||||
+ if(wc_rrset)
|
||||
+ ((struct packed_rrset_data*)wc_rrset->
|
||||
+ entry.data)->security = sec_status_bogus;
|
||||
return;
|
||||
}
|
||||
if(wc && !wc_cached && env->cfg->aggressive_nsec) {
|
||||
@@ -1038,7 +1044,7 @@ validate_positive_response(struct module_env* env, struct val_env* ve,
|
||||
env->alloc, *env->now);
|
||||
wc_cached = 1;
|
||||
}
|
||||
-
|
||||
+ if(wc) wc_rrset = s;
|
||||
}
|
||||
|
||||
/* validate the AUTHORITY section as well - this will generally be
|
||||
@@ -1095,6 +1101,9 @@ validate_positive_response(struct module_env* env, struct val_env* ve,
|
||||
"did not exist");
|
||||
chase_reply->security = sec_status_bogus;
|
||||
update_reason_bogus(chase_reply, LDNS_EDE_DNSSEC_BOGUS);
|
||||
+ if(wc_rrset)
|
||||
+ ((struct packed_rrset_data*)wc_rrset->
|
||||
+ entry.data)->security = sec_status_bogus;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1496,6 +1505,16 @@ validate_any_response(struct module_env* env, struct val_env* ve,
|
||||
"did not exist");
|
||||
chase_reply->security = sec_status_bogus;
|
||||
update_reason_bogus(chase_reply, LDNS_EDE_DNSSEC_BOGUS);
|
||||
+ /* Make the expanded name and wildcard RRSIG rrsets bogus */
|
||||
+ for(i=0; i<chase_reply->an_numrrsets; i++) {
|
||||
+ uint8_t* cwc = NULL;
|
||||
+ size_t cwl = 0;
|
||||
+ s = chase_reply->rrsets[i];
|
||||
+ if(val_rrset_wildcard(s, &cwc, &cwl) && cwc) {
|
||||
+ ((struct packed_rrset_data*)s->
|
||||
+ entry.data)->security = sec_status_bogus;
|
||||
+ }
|
||||
+ }
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1533,6 +1552,9 @@ validate_cname_response(struct module_env* env, struct val_env* ve,
|
||||
uint8_t* wc = NULL;
|
||||
size_t wl;
|
||||
int wc_NSEC_ok = 0;
|
||||
+ /* This is used to update the RRset cache, with the combination
|
||||
+ * of the dname expansion and this wildcard, for security status. */
|
||||
+ struct ub_packed_rrset_key* wc_rrset = NULL;
|
||||
int nsec3s_seen = 0;
|
||||
size_t i;
|
||||
struct ub_packed_rrset_key* s;
|
||||
@@ -1553,6 +1575,7 @@ validate_cname_response(struct module_env* env, struct val_env* ve,
|
||||
update_reason_bogus(chase_reply, LDNS_EDE_DNSSEC_BOGUS);
|
||||
return;
|
||||
}
|
||||
+ if(wc) wc_rrset = s;
|
||||
|
||||
/* Refuse wildcarded DNAMEs rfc 4597.
|
||||
* Do not follow a wildcarded DNAME because
|
||||
@@ -1564,6 +1587,9 @@ validate_cname_response(struct module_env* env, struct val_env* ve,
|
||||
ntohs(s->rk.type), ntohs(s->rk.rrset_class));
|
||||
chase_reply->security = sec_status_bogus;
|
||||
update_reason_bogus(chase_reply, LDNS_EDE_DNSSEC_BOGUS);
|
||||
+ if(wc_rrset)
|
||||
+ ((struct packed_rrset_data*)wc_rrset->
|
||||
+ entry.data)->security = sec_status_bogus;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1628,6 +1654,9 @@ validate_cname_response(struct module_env* env, struct val_env* ve,
|
||||
"did not exist");
|
||||
chase_reply->security = sec_status_bogus;
|
||||
update_reason_bogus(chase_reply, LDNS_EDE_DNSSEC_BOGUS);
|
||||
+ if(wc_rrset)
|
||||
+ ((struct packed_rrset_data*)wc_rrset->
|
||||
+ entry.data)->security = sec_status_bogus;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ SRC_URI = "git://github.com/NLnetLabs/unbound.git;protocol=https;branch=master;t
|
||||
file://CVE-2026-42960.patch \
|
||||
file://CVE-2026-44390.patch \
|
||||
file://CVE-2026-44608.patch \
|
||||
file://CVE-2026-46582.patch \
|
||||
"
|
||||
|
||||
SRCREV = "f6269baa605d31859f28770e01a24e3677e5f82c"
|
||||
|
||||
Reference in New Issue
Block a user