Looking at this, it has been submitted by another contributor some time
ago[1], but it seems it wasn't applied. Was this missed accidentally, or
are there some issues with it?

[1]: https://lists.openembedded.org/g/openembedded-devel/message/121294

On 1/9/26 10:28, Ankur Tyagi via lists.openembedded.org wrote:
> From: Ankur Tyagi <[email protected]>
>
> Details: https://nvd.nist.gov/vuln/detail/CVE-2025-5994
>
> Signed-off-by: Ankur Tyagi <[email protected]>
> ---
>  .../unbound/unbound/CVE-2025-5994.patch       | 276 ++++++++++++++++++
>  .../recipes-support/unbound/unbound_1.19.3.bb |   1 +
>  2 files changed, 277 insertions(+)
>  create mode 100644 
> meta-networking/recipes-support/unbound/unbound/CVE-2025-5994.patch
>
> diff --git 
> a/meta-networking/recipes-support/unbound/unbound/CVE-2025-5994.patch 
> b/meta-networking/recipes-support/unbound/unbound/CVE-2025-5994.patch
> new file mode 100644
> index 0000000000..3056fe3683
> --- /dev/null
> +++ b/meta-networking/recipes-support/unbound/unbound/CVE-2025-5994.patch
> @@ -0,0 +1,276 @@
> +From 380b53b92a6824a581f3f6079dfddd73631933fa Mon Sep 17 00:00:00 2001
> +From: "W.C.A. Wijngaards" <[email protected]>
> +Date: Wed, 16 Jul 2025 10:02:01 +0200
> +Subject: [PATCH] - Fix RebirthDay Attack CVE-2025-5994, reported by Xiang Li
> + from AOSP   Lab Nankai University.
> +
> +CVE: CVE-2025-5994
> +Upstream-Status: Backport 
> [https://github.com/NLnetLabs/unbound/commit/5bf82f246481098a6473f296b21fc1229d276c0f]
> +Signed-off-by: Ankur Tyagi <[email protected]>
> +---
> + edns-subnet/subnetmod.c | 152 ++++++++++++++++++++++++++++++++++++----
> + edns-subnet/subnetmod.h |   4 ++
> + 2 files changed, 142 insertions(+), 14 deletions(-)
> +
> +diff --git a/edns-subnet/subnetmod.c b/edns-subnet/subnetmod.c
> +index cefde84e..9c0c914b 100644
> +--- a/edns-subnet/subnetmod.c
> ++++ b/edns-subnet/subnetmod.c
> +@@ -51,6 +51,7 @@
> + #include "services/cache/dns.h"
> + #include "util/module.h"
> + #include "util/regional.h"
> ++#include "util/fptr_wlist.h"
> + #include "util/storage/slabhash.h"
> + #include "util/config_file.h"
> + #include "util/data/msgreply.h"
> +@@ -152,7 +153,8 @@ int ecs_whitelist_check(struct query_info* qinfo,
> + 
> +     /* Cache by default, might be disabled after parsing EDNS option
> +      * received from nameserver. */
> +-    if(!iter_stub_fwd_no_cache(qstate, &qstate->qinfo, NULL, NULL)) {
> ++    if(!iter_stub_fwd_no_cache(qstate, &qstate->qinfo, NULL, NULL)
> ++            && sq->ecs_client_in.subnet_validdata) {
> +             qstate->no_cache_store = 0;
> +     }
> + 
> +@@ -504,6 +506,69 @@ common_prefix(uint8_t *a, uint8_t *b, uint8_t net)
> +     return !memcmp(a, b, n) && ((net % 8) == 0 || a[n] == b[n]);
> + }
> + 
> ++/**
> ++ * Create sub request that looks up the query.
> ++ * @param qstate: query state
> ++ * @param sq: subnet qstate
> ++ * @return false on failure.
> ++ */
> ++static int
> ++generate_sub_request(struct module_qstate *qstate, struct subnet_qstate* sq)
> ++{
> ++    struct module_qstate* subq = NULL;
> ++    uint16_t qflags = 0; /* OPCODE QUERY, no flags */
> ++    int prime = 0;
> ++    int valrec = 0;
> ++    struct query_info qinf;
> ++    qinf.qname = qstate->qinfo.qname;
> ++    qinf.qname_len = qstate->qinfo.qname_len;
> ++    qinf.qtype = qstate->qinfo.qtype;
> ++    qinf.qclass = qstate->qinfo.qclass;
> ++    qinf.local_alias = NULL;
> ++
> ++    qflags |= BIT_RD;
> ++    if((qstate->query_flags & BIT_CD)!=0) {
> ++            qflags |= BIT_CD;
> ++            valrec = 1;
> ++    }
> ++
> ++    fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
> ++    if(!(*qstate->env->attach_sub)(qstate, &qinf, qflags, prime, valrec,
> ++            &subq)) {
> ++            return 0;
> ++    }
> ++    if(subq) {
> ++            /* It is possible to access the subquery module state. */
> ++            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;
> ++            }
> ++    }
> ++    return 1;
> ++}
> ++
> ++/**
> ++ * Perform the query without subnet
> ++ * @param qstate: query state
> ++ * @param sq: subnet qstate
> ++ * @return module state
> ++ */
> ++static enum module_ext_state
> ++generate_lookup_without_subnet(struct module_qstate *qstate,
> ++    struct subnet_qstate* sq)
> ++{
> ++    verbose(VERB_ALGO, "subnetcache: make subquery to look up without 
> subnet");
> ++    if(!generate_sub_request(qstate, sq)) {
> ++            verbose(VERB_ALGO, "Could not generate sub query");
> ++            qstate->return_rcode = LDNS_RCODE_FORMERR;
> ++            qstate->return_msg = NULL;
> ++            return module_finished;
> ++    }
> ++    sq->wait_subquery = 1;
> ++    return module_wait_subquery;
> ++}
> ++
> + static enum module_ext_state
> + eval_response(struct module_qstate *qstate, int id, struct subnet_qstate 
> *sq)
> + {
> +@@ -539,14 +604,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");
> +-            if(!sq->started_no_cache_store) {
> +-                    lock_rw_wrlock(&sne->biglock);
> +-                    update_cache(qstate, id);
> +-                    lock_rw_unlock(&sne->biglock);
> +-            }
> +-            if (sq->subnet_downstream)
> +-                    cp_edns_bad_response(c_out, c_in);
> +-            return module_finished;
> ++            return generate_lookup_without_subnet(qstate, sq);
> +     }
> + 
> +     /* Purposefully there was no sent subnet, and there is consequently
> +@@ -571,14 +629,14 @@ eval_response(struct module_qstate *qstate, int id, 
> struct subnet_qstate *sq)
> +             !common_prefix(s_out->subnet_addr, s_in->subnet_addr, 
> +                     s_out->subnet_source_mask))
> +     {
> +-            /* we can not accept, restart query without option */
> ++            /* we can not accept, perform query without option */
> +             verbose(VERB_QUERY, "subnetcache: forged data");
> +             s_out->subnet_validdata = 0;
> +             (void)edns_opt_list_remove(&qstate->edns_opts_back_out,
> +                     qstate->env->cfg->client_subnet_opcode);
> +             sq->subnet_sent = 0;
> +             sq->subnet_sent_no_subnet = 0;
> +-            return module_restart_next;
> ++            return generate_lookup_without_subnet(qstate, sq);
> +     }
> + 
> +     lock_rw_wrlock(&sne->biglock);
> +@@ -763,6 +821,9 @@ ecs_edns_back_parsed(struct module_qstate* qstate, int 
> id,
> +     } else if(sq->subnet_sent_no_subnet) {
> +             /* The answer can be stored as scope 0, not in global cache. */
> +             qstate->no_cache_store = 1;
> ++    } else if(sq->subnet_sent) {
> ++            /* Need another query to be able to store in global cache. */
> ++            qstate->no_cache_store = 1;
> +     }
> + 
> +     return 1;
> +@@ -780,6 +841,32 @@ subnetmod_operate(struct module_qstate *qstate, enum 
> module_ev event,
> +             strmodulevent(event));
> +     log_query_info(VERB_QUERY, "subnetcache operate: query", 
> &qstate->qinfo);
> + 
> ++    if(sq && sq->wait_subquery_done) {
> ++            /* The subquery lookup returned. */
> ++            if(sq->ecs_client_in.subnet_source_mask == 0 &&
> ++                    edns_opt_list_find(qstate->edns_opts_front_in,
> ++                            qstate->env->cfg->client_subnet_opcode)) {
> ++                    if(!sq->started_no_cache_store &&
> ++                            qstate->return_msg) {
> ++                            lock_rw_wrlock(&sne->biglock);
> ++                            update_cache(qstate, id);
> ++                            lock_rw_unlock(&sne->biglock);
> ++                    }
> ++                    if (sq->subnet_downstream)
> ++                            cp_edns_bad_response(&sq->ecs_client_out,
> ++                                    &sq->ecs_client_in);
> ++                    /* It is a scope zero lookup, append edns subnet
> ++                     * option to the querier. */
> ++                    subnet_ecs_opt_list_append(&sq->ecs_client_out,
> ++                            &qstate->edns_opts_front_out, qstate,
> ++                            qstate->region);
> ++            }
> ++            sq->wait_subquery_done = 0;
> ++            qstate->ext_state[id] = module_finished;
> ++            qstate->no_cache_store = sq->started_no_cache_store;
> ++            qstate->no_cache_lookup = sq->started_no_cache_lookup;
> ++            return;
> ++    }
> +     if((event == module_event_new || event == module_event_pass) &&
> +             sq == NULL) {
> +             struct edns_option* ecs_opt;
> +@@ -790,6 +877,8 @@ subnetmod_operate(struct module_qstate *qstate, enum 
> module_ev event,
> +             }
> + 
> +             sq = (struct subnet_qstate*)qstate->minfo[id];
> ++            if(sq->wait_subquery)
> ++                    return; /* Wait for that subquery to return */
> + 
> +             if((ecs_opt = edns_opt_list_find(
> +                     qstate->edns_opts_front_in,
> +@@ -819,6 +908,14 @@ subnetmod_operate(struct module_qstate *qstate, enum 
> module_ev event,
> +                     /* No clients are interested in result or we could not
> +                      * parse it, we don't do client subnet */
> +                     sq->ecs_server_out.subnet_validdata = 0;
> ++                    if(edns_opt_list_find(qstate->edns_opts_front_in,
> ++                            qstate->env->cfg->client_subnet_opcode)) {
> ++                            /* aggregated this deaggregated state */
> ++                            qstate->ext_state[id] =
> ++                                    generate_lookup_without_subnet(
> ++                                    qstate, sq);
> ++                            return;
> ++                    }
> +                     verbose(VERB_ALGO, "subnetcache: pass to next module");
> +                     qstate->ext_state[id] = module_wait_module;
> +                     return;
> +@@ -859,6 +956,14 @@ subnetmod_operate(struct module_qstate *qstate, enum 
> module_ev event,
> +                     }
> +                     lock_rw_unlock(&sne->biglock);
> +             }
> ++            if(sq->ecs_client_in.subnet_source_mask == 0 &&
> ++                    edns_opt_list_find(qstate->edns_opts_front_in,
> ++                            qstate->env->cfg->client_subnet_opcode)) {
> ++                    /* client asked for resolution without edns subnet */
> ++                    qstate->ext_state[id] = generate_lookup_without_subnet(
> ++                            qstate, sq);
> ++                    return;
> ++            }
> +             
> +             sq->ecs_server_out.subnet_addr_fam =
> +                     sq->ecs_client_in.subnet_addr_fam;
> +@@ -895,6 +1000,8 @@ subnetmod_operate(struct module_qstate *qstate, enum 
> module_ev event,
> +             qstate->ext_state[id] = module_wait_module;
> +             return;
> +     }
> ++    if(sq && sq->wait_subquery)
> ++            return; /* Wait for that subquery to return */
> +     /* Query handed back by next module, we have a 'final' answer */
> +     if(sq && event == module_event_moddone) {
> +             qstate->ext_state[id] = eval_response(qstate, id, sq);
> +@@ -943,10 +1050,27 @@ subnetmod_clear(struct module_qstate 
> *ATTR_UNUSED(qstate),
> + }
> + 
> + void
> +-subnetmod_inform_super(struct module_qstate *ATTR_UNUSED(qstate),
> +-    int ATTR_UNUSED(id), struct module_qstate *ATTR_UNUSED(super))
> ++subnetmod_inform_super(struct module_qstate *qstate, int id,
> ++    struct module_qstate *super)
> + {
> +-    /* Not used */
> ++    struct subnet_qstate* super_sq =
> ++            (struct subnet_qstate*)super->minfo[id];
> ++    log_query_info(VERB_ALGO, "subnetcache inform_super: query",
> ++            &super->qinfo);
> ++    super_sq->wait_subquery = 0;
> ++    super_sq->wait_subquery_done = 1;
> ++    if(qstate->return_rcode != LDNS_RCODE_NOERROR ||
> ++            !qstate->return_msg) {
> ++            super->return_msg = NULL;
> ++            super->return_rcode = LDNS_RCODE_SERVFAIL;
> ++            return;
> ++    }
> ++    super->return_rcode = LDNS_RCODE_NOERROR;
> ++    super->return_msg = dns_copy_msg(qstate->return_msg, super->region);
> ++    if(!super->return_msg) {
> ++            log_err("subnetcache: copy response, out of memory");
> ++            super->return_rcode = LDNS_RCODE_SERVFAIL;
> ++    }
> + }
> + 
> + size_t
> +diff --git a/edns-subnet/subnetmod.h b/edns-subnet/subnetmod.h
> +index 1ff8a23e..3893820f 100644
> +--- a/edns-subnet/subnetmod.h
> ++++ b/edns-subnet/subnetmod.h
> +@@ -102,6 +102,10 @@ struct subnet_qstate {
> +     int started_no_cache_store;
> +     /** has the subnet module been started with no_cache_lookup? */
> +     int started_no_cache_lookup;
> ++    /** Wait for subquery that has been started for nonsubnet lookup. */
> ++    int wait_subquery;
> ++    /** The subquery waited for is done. */
> ++    int wait_subquery_done;
> + };
> + 
> + void subnet_data_delete(void* d, void* ATTR_UNUSED(arg));
> diff --git a/meta-networking/recipes-support/unbound/unbound_1.19.3.bb 
> b/meta-networking/recipes-support/unbound/unbound_1.19.3.bb
> index 076f03f2ae..7e3e37406f 100644
> --- a/meta-networking/recipes-support/unbound/unbound_1.19.3.bb
> +++ b/meta-networking/recipes-support/unbound/unbound_1.19.3.bb
> @@ -16,6 +16,7 @@ SRC_URI = 
> "git://github.com/NLnetLabs/unbound.git;protocol=https;nobranch=1 \
>             file://CVE-2024-43167.patch \
>             file://CVE-2024-43168_1.patch \
>             file://CVE-2024-43168_2.patch \
> +           file://CVE-2025-5994.patch \
>             "
>  SRCREV = "48b6c60a24e9a5d6d369a7a37c9fe2a767f26abd"
>  
>
> 
>

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

Reply via email to