From 1db42403d08e83ae8ae05bc33de53c338c4eb47d Mon Sep 17 00:00:00 2001 From: eaglegai Date: Tue, 19 Aug 2025 02:21:35 +0000 Subject: [PATCH] backport upstream to add CVE-2025-5994's after patches (cherry picked from commit 160980d236d191df1d197a6aedd5b999ae48f4f2) --- ...-subquery-is-nonsubnet-and-scopezero.patch | 149 ++++++++++++++++++ ...create-a-subquery-errors-as-servfail.patch | 26 +++ unbound.spec | 10 +- 3 files changed, 184 insertions(+), 1 deletion(-) create mode 100644 backport-CVE-2025-5994-after-fix-edns-subnet-when-subquery-is-nonsubnet-and-scopezero.patch create mode 100644 backport-CVE-2025-5994-after-fix-that-edns-subnet-failure-to-create-a-subquery-errors-as-servfail.patch diff --git a/backport-CVE-2025-5994-after-fix-edns-subnet-when-subquery-is-nonsubnet-and-scopezero.patch b/backport-CVE-2025-5994-after-fix-edns-subnet-when-subquery-is-nonsubnet-and-scopezero.patch new file mode 100644 index 0000000..c454263 --- /dev/null +++ b/backport-CVE-2025-5994-after-fix-edns-subnet-when-subquery-is-nonsubnet-and-scopezero.patch @@ -0,0 +1,149 @@ +From 305adf12bfa580552faa61af51ff5e17556015b7 Mon Sep 17 00:00:00 2001 +From: "W.C.A. Wijngaards" +Date: Wed, 6 Aug 2025 12:01:42 +0200 +Subject: [PATCH] - Fix edns subnet, so that the subquery without subnet is + stored in global cache if the querier used 0.0.0.0/0 and the name and + address do not receive subnet treatment. If the name and address are + configured for subnet, it is stored in the subnet cache. + +Conflict: change subnetmod.c context +Reference: https://github.com/NLnetLabs/unbound/commit/305adf12bfa580552faa61af51ff5e17556015b7 + +--- + edns-subnet/subnetmod.c | 43 ++++++++++++++++++++++++++++++++++------- + edns-subnet/subnetmod.h | 4 ++++ + 2 files changed, 40 insertions(+), 7 deletions(-) + +diff --git a/edns-subnet/subnetmod.c b/edns-subnet/subnetmod.c +index c763c5f1a..6f71129d9 100644 +--- a/edns-subnet/subnetmod.c ++++ b/edns-subnet/subnetmod.c +@@ -154,6 +154,21 @@ int ecs_whitelist_check(struct query_info* qinfo, + return 1; + sn_env = (struct subnet_env*)qstate->env->modinfo[id]; + ++ if(sq->is_subquery_nonsubnet) { ++ if(sq->is_subquery_scopezero) { ++ /* Check if the result can be stored in the global cache, ++ * this is okay if the address and name are not configured ++ * as subnet address and subnet zone. */ ++ if(!ecs_is_whitelisted(sn_env->whitelist, ++ addr, addrlen, qinfo->qname, qinfo->qname_len, ++ qinfo->qclass)) { ++ verbose(VERB_ALGO, "subnet store subquery global, name and addr have no subnet treatment."); ++ qstate->no_cache_store = 0; ++ } ++ } ++ return 1; ++ } ++ + /* Cache by default, might be disabled after parsing EDNS option + * received from nameserver. */ + if(!iter_stub_fwd_no_cache(qstate, &qstate->qinfo, NULL, NULL) +@@ -527,11 +542,12 @@ common_prefix(uint8_t *a, uint8_t *b, uint8_t net) + /** + * Create sub request that looks up the query. + * @param qstate: query state ++ * @param id: module id. + * @param sq: subnet qstate + * @return false on failure. + */ + static int +-generate_sub_request(struct module_qstate *qstate, struct subnet_qstate* sq) ++generate_sub_request(struct module_qstate *qstate, int id, struct subnet_qstate* sq) + { + struct module_qstate* subq = NULL; + uint16_t qflags = 0; /* OPCODE QUERY, no flags */ +@@ -557,10 +573,22 @@ generate_sub_request(struct module_qstate *qstate, struct subnet_qstate* sq) + } + if(subq) { + /* It is possible to access the subquery module state. */ ++ struct subnet_qstate* subsq; ++ if(!subnet_new_qstate(subq, id)) { ++ verbose(VERB_ALGO, "Could not allocate new subnet qstate"); ++ return 0; ++ } ++ subsq = (struct subnet_qstate*)subq->minfo[id]; ++ subsq->is_subquery_nonsubnet = 1; ++ ++ /* When the client asks 0.0.0.0/0 and the name is not treated ++ * as subnet, it is to be stored in the global cache. ++ * Store that the client asked for that, if so. */ + if(sq->ecs_client_in.subnet_source_mask == 0 && + edns_opt_list_find(qstate->edns_opts_front_in, + qstate->env->cfg->client_subnet_opcode)) { + subq->no_cache_store = 1; ++ subsq->is_subquery_scopezero = 1; + } + } + return 1; +@@ -569,15 +597,16 @@ generate_sub_request(struct module_qstate *qstate, struct subnet_qstate* sq) + /** + * Perform the query without subnet + * @param qstate: query state ++ * @param id: module id. + * @param sq: subnet qstate + * @return module state + */ + static enum module_ext_state +-generate_lookup_without_subnet(struct module_qstate *qstate, ++generate_lookup_without_subnet(struct module_qstate *qstate, int id, + struct subnet_qstate* sq) + { + verbose(VERB_ALGO, "subnetcache: make subquery to look up without subnet"); +- if(!generate_sub_request(qstate, sq)) { ++ if(!generate_sub_request(qstate, id, sq)) { + verbose(VERB_ALGO, "Could not generate sub query"); + qstate->return_rcode = LDNS_RCODE_FORMERR; + qstate->return_msg = NULL; +@@ -622,7 +651,7 @@ eval_response(struct module_qstate *qstate, int id, struct subnet_qstate *sq) + * is still useful to put it in the edns subnet cache for + * when a client explicitly asks for subnet specific answer. */ + verbose(VERB_QUERY, "subnetcache: Authority indicates no support"); +- return generate_lookup_without_subnet(qstate, sq); ++ return generate_lookup_without_subnet(qstate, id, sq); + } + + /* Being here means we have asked for and got a subnet specific +@@ -654,7 +683,7 @@ eval_response(struct module_qstate *qstate, int id, struct subnet_qstate *sq) + (void)edns_opt_list_remove(&qstate->edns_opts_back_out, + qstate->env->cfg->client_subnet_opcode); + sq->subnet_sent = 0; +- return generate_lookup_without_subnet(qstate, sq); ++ return generate_lookup_without_subnet(qstate, id, sq); + } + + lock_rw_wrlock(&sne->biglock); +@@ -945,7 +974,7 @@ subnetmod_operate(struct module_qstate *qstate, enum module_ev event, + /* aggregated this deaggregated state */ + qstate->ext_state[id] = + generate_lookup_without_subnet( +- qstate, sq); ++ qstate, id, sq); + return; + } + verbose(VERB_ALGO, "subnetcache: pass to next module"); +@@ -993,7 +1022,7 @@ subnetmod_operate(struct module_qstate *qstate, enum module_ev event, + qstate->env->cfg->client_subnet_opcode)) { + /* client asked for resolution without edns subnet */ + qstate->ext_state[id] = generate_lookup_without_subnet( +- qstate, sq); ++ qstate, id, sq); + return; + } + +diff --git a/edns-subnet/subnetmod.h b/edns-subnet/subnetmod.h +index 3893820fa..d2d9e957f 100644 +--- a/edns-subnet/subnetmod.h ++++ b/edns-subnet/subnetmod.h +@@ -106,6 +106,10 @@ struct subnet_qstate { + int wait_subquery; + /** The subquery waited for is done. */ + int wait_subquery_done; ++ /** The subnet state is a subquery state for nonsubnet lookup. */ ++ int is_subquery_nonsubnet; ++ /** This is a subquery, and it is made due to a scope zero request. */ ++ int is_subquery_scopezero; + }; + + void subnet_data_delete(void* d, void* ATTR_UNUSED(arg)); diff --git a/backport-CVE-2025-5994-after-fix-that-edns-subnet-failure-to-create-a-subquery-errors-as-servfail.patch b/backport-CVE-2025-5994-after-fix-that-edns-subnet-failure-to-create-a-subquery-errors-as-servfail.patch new file mode 100644 index 0000000..71035b3 --- /dev/null +++ b/backport-CVE-2025-5994-after-fix-that-edns-subnet-failure-to-create-a-subquery-errors-as-servfail.patch @@ -0,0 +1,26 @@ +From 3ec5d78ac9a8b38ecaf0cdef83a230e76418330f Mon Sep 17 00:00:00 2001 +From: "W.C.A. Wijngaards" +Date: Thu, 7 Aug 2025 16:09:47 +0200 +Subject: [PATCH] - Fix that edns-subnet failure to create a subquery errors as + servfail, and not formerror. + +Conflict: delete change about doc/Changelog +Reference: https://github.com/NLnetLabs/unbound/commit/3ec5d78ac9a8b38ecaf0cdef83a230e76418330f + +--- + edns-subnet/subnetmod.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletion(-) + +diff --git a/edns-subnet/subnetmod.c b/edns-subnet/subnetmod.c +index 6f71129d9..88310a785 100644 +--- a/edns-subnet/subnetmod.c ++++ b/edns-subnet/subnetmod.c +@@ -608,7 +608,7 @@ generate_lookup_without_subnet(struct module_qstate *qstate, int id, + verbose(VERB_ALGO, "subnetcache: make subquery to look up without subnet"); + if(!generate_sub_request(qstate, id, sq)) { + verbose(VERB_ALGO, "Could not generate sub query"); +- qstate->return_rcode = LDNS_RCODE_FORMERR; ++ qstate->return_rcode = LDNS_RCODE_SERVFAIL; + qstate->return_msg = NULL; + return module_finished; + } diff --git a/unbound.spec b/unbound.spec index a15cb1a..5fd7e7f 100644 --- a/unbound.spec +++ b/unbound.spec @@ -2,7 +2,7 @@ Name: unbound Version: 1.17.1 -Release: 12 +Release: 13 Summary: Unbound is a validating, recursive, caching DNS resolver License: BSD-3-Clause Url: https://nlnetlabs.nl/projects/unbound/about/ @@ -36,6 +36,8 @@ Patch12: backport-004-CVE-2024-43168.patch Patch13: backport-CVE-2024-8508.patch Patch14: backport-check-before-use-daemon-shm_info.patch Patch15: backport-CVE-2025-5994.patch +Patch16: backport-CVE-2025-5994-after-fix-edns-subnet-when-subquery-is-nonsubnet-and-scopezero.patch +Patch17: backport-CVE-2025-5994-after-fix-that-edns-subnet-failure-to-create-a-subquery-errors-as-servfail.patch BuildRequires: make flex swig pkgconfig systemd BuildRequires: libevent-devel expat-devel openssl-devel python3-devel @@ -272,6 +274,12 @@ popd %{_mandir}/man* %changelog +* Tue Aug 19 2025 gaihuiying - 1.17.1-13 +- Type:bugfix +- CVE:NA +- SUG:NA +- DESC:backport upstream to add CVE-2025-5994's after patches + * Mon Aug 04 2025 gaihuiying - 1.17.1-12 - Type:cves - CVE:CVE-2025-5994 -- Gitee