From patchwork Sun Sep 27 00:39:11 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ankur Tyagi X-Patchwork-Id: 99264 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 86705C9833E for ; Sun, 27 Sep 2026 00:39:40 +0000 (UTC) Received: from mail-pj2-f43.google.com (mail-pj2-f43.google.com [74.125.227.171]) by mx.groups.io with SMTP id smtpd.msgproc01-g2.29994.1790469569801429810 for ; Sat, 26 Sep 2026 17:39:29 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@gmail.com header.s=20251104 header.b=GPlYnsxh; spf=pass (domain: gmail.com, ip: 74.125.227.171, mailfrom: ankur.tyagi85@gmail.com) Received: by mail-pj2-f43.google.com with SMTP id 98e67ed59e1d1-396ccafb752so1018791a91.0 for ; Sat, 26 Sep 2026 17:39:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1790469569; x=1791074369; darn=lists.openembedded.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to:content-type; bh=N8zhEvPPU1tlcLI5eM+mzVbfuOveqqujSkFW4Xtd3Qk=; b=GPlYnsxh/vbTJmBGR/BV43s6XTPuxuY7jVHnJPZJbrS3JrVxVV5wmPtSRVT3b505cY NL9tQ7V3zx567hdYYkLOYALWFnCTEmgKKhBwjLVIWmgZxfkYj4HxcZUwzVg1dmKMFvQk lD5QhkmNnvwxZQmv6C6EfAW0SSn9ymY0I+3ZtDho1wF5+8waFKZ+Lg1SKYbU5hhmiUrC xc7xuv7p48YDoY93qZSaz9mvbSDLN6PhMqyozlo03r/rYLf5CbxPXqzYvny+xUBSMyhs pWicXlwYm5AtjWgDy+ltZv3G6VzcHpNSAW/i+S5Szdl1SM+5OuYu51MC8iWYCvN+Dn3s cVaw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1790469569; x=1791074369; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=N8zhEvPPU1tlcLI5eM+mzVbfuOveqqujSkFW4Xtd3Qk=; b=2dOXoFpDYGL5oWILAcB4azcEr/OXnNlmmfI6Yfw4hCCU4GvUqIrOR9mC7fhoUlXxD5 o4tUINbPFIwvhGDxiM+UrfKFKuAvkvrvblTOhc3mD0JPj8C09RlTbqmDXGVUBfISkDx9 xrLnrUcjF1V+QWrC5D3jrioKNAKCHGOuu7MmHhdULZ3bcoVZO5CFaDoHQbmMpWgSfjuk emctzLCEqJU0uYML8YvndxmDXP9GtHk1TWt0NyxndrZ5TKXwyaM7iRYtcL3Z9UOCTG08 unb1QIiTPYar6RMnQLD7ThfLtr9BaOyS93qY9Ev8hjGs5QSCnER/xgzh0ugQo/trmN/T EXCQ== X-Gm-Message-State: AFq9FYIdZFmiIY+oRSL2XpgIv1V9V3wsPF4AQy0AoK7fO7hh8WfmkPic L1RXs+zmsLdebZq8UBK99ybXYED6lXa2J6K/actsszXEhzcQxx56dIuXg9a6Bw== X-Gm-Gg: AYBFou1ms1GFbRyvLPcL2abSX5Bmx/JQ16E8Sy4/AVsiksGhkUkP1Ns0/aKK4CNiFBO 7TZGLHcA+JhHs2cT4O48hoY7vpojOk8N921wywJLszPcsvEv+5N4sgY+EHTdKjW9z58OErU4NRE 54tX/zPSsBbxPwpq82j82vsn8rw0DtqwVAT/MVqCBBEDMq5QrGA1gGVGTPqWrt0HuVW6M4BX7uX ayQ6juWl3q7twUQbIqtysiphai1a3RMu/3D5VXSi4CJLbuw0PoUn7nwpq80JWHRw8O9s7AzO8nV K8WBI9XgmD1YjVVa343cgrqOwxDPg43rdGjgHKye9htC6jC5+PbBeoeJ47Rv1qylAkKXk3/fFVT eO9D5nqE0OU/FsOxcchbrB0PXg9NxSNGeRti6IfJGghtuyTOlywtcuVg2TGPDbmmduWojQQct/u Ewl0mASs9LArNVEYqZUAHR+iYusjcePWU6gxdEcDypsO4iTVH1bEANoozwiSWGLfzUyV3jt0RL2 ESwX22yiGeoY1jQnzFRsiY= X-Received: by 2002:a17:90b:44:b0:3a0:cc33:2285 with SMTP id 98e67ed59e1d1-3a0cc3324bcmr3598687a91.22.1790469568957; Sat, 26 Sep 2026 17:39:28 -0700 (PDT) Received: from NVAPF55DW0D-IPD.. ([203.211.104.195]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-3a0d22281f0sm2876420a91.1.2026.09.26.17.39.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 26 Sep 2026 17:39:28 -0700 (PDT) From: ankur.tyagi85@gmail.com To: openembedded-devel@lists.openembedded.org Cc: Ankur Tyagi Subject: [oe][meta-networking][wrynose][PATCH 1/11] unbound: patch CVE-2026-80225 Date: Sun, 27 Sep 2026 13:39:11 +1300 Message-ID: <20260927003921.746786-1-ankur.tyagi85@gmail.com> X-Mailer: git-send-email 2.43.0 MIME-Version: 1.0 List-Id: X-Webhook-Received: from 45-33-107-173.ip.linodeusercontent.com [45.33.107.173] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Sun, 27 Sep 2026 00:39:40 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-devel/message/130320 From: Ankur Tyagi Details: https://nvd.nist.gov/vuln/detail/cve-2026-80225 Signed-off-by: Ankur Tyagi --- .../unbound/unbound/CVE-2026-80225.patch | 286 ++++++++++++++++++ .../recipes-support/unbound/unbound_1.24.2.bb | 1 + 2 files changed, 287 insertions(+) create mode 100644 meta-networking/recipes-support/unbound/unbound/CVE-2026-80225.patch diff --git a/meta-networking/recipes-support/unbound/unbound/CVE-2026-80225.patch b/meta-networking/recipes-support/unbound/unbound/CVE-2026-80225.patch new file mode 100644 index 0000000000..fb7dda7a15 --- /dev/null +++ b/meta-networking/recipes-support/unbound/unbound/CVE-2026-80225.patch @@ -0,0 +1,286 @@ +From 5d92dbc699c7a347be74b3752b1c3ee690e4dec1 Mon Sep 17 00:00:00 2001 +From: "W.C.A. Wijngaards" +Date: Wed, 16 Sep 2026 09:16:29 +0200 +Subject: [PATCH] - Fix CVE-2026-80225, Possible degradation of service from + continuous queries on the same TCP/DoT connection. Thanks to Qifan Zhang + from Palo Alto Networks for the report. + +(cherry picked from commit e619ead2dbcde8fc47f03b2ac68987b3377da4c7) + +CVE: CVE-2026-80225 +Upstream-Status: Backport [https://github.com/NLnetLabs/unbound/commit/e619ead2dbcde8fc47f03b2ac68987b3377da4c7] + +Signed-off-by: Ankur Tyagi +--- + services/listen_dnsport.c | 12 ++++++- + services/listen_dnsport.h | 8 ++++- + testcode/testbound.c | 10 ++++++ + util/fptr_wlist.c | 2 ++ + util/netevent.c | 66 ++++++++++++++++++++++++++++++++++++++- + util/netevent.h | 9 ++++++ + 6 files changed, 104 insertions(+), 3 deletions(-) + +diff --git a/services/listen_dnsport.c b/services/listen_dnsport.c +index d49d4ad4c..9b6fb557c 100644 +--- a/services/listen_dnsport.c ++++ b/services/listen_dnsport.c +@@ -2134,7 +2134,7 @@ void listen_start_accept(struct listen_dnsport* listen) + } + + struct tcp_req_info* +-tcp_req_info_create(struct sldns_buffer* spoolbuf) ++tcp_req_info_create(struct comm_base* base, struct sldns_buffer* spoolbuf) + { + struct tcp_req_info* req = (struct tcp_req_info*)malloc(sizeof(*req)); + if(!req) { +@@ -2142,6 +2142,12 @@ tcp_req_info_create(struct sldns_buffer* spoolbuf) + return NULL; + } + memset(req, 0, sizeof(*req)); ++ req->read_again_timer = comm_timer_create(base, tcp_read_again_cb, req); ++ if(!req->read_again_timer) { ++ log_err("malloc failure"); ++ free(req); ++ return NULL; ++ } + req->spool_buffer = spoolbuf; + return req; + } +@@ -2151,6 +2157,7 @@ tcp_req_info_delete(struct tcp_req_info* req) + { + if(!req) return; + tcp_req_info_clear(req); ++ comm_timer_delete(req->read_again_timer); + /* cp is pointer back to commpoint that owns this struct and + * called delete on us */ + /* spool_buffer is shared udp buffer, not deleted here */ +@@ -2189,6 +2196,9 @@ void tcp_req_info_clear(struct tcp_req_info* req) + req->done_req_list = NULL; + req->num_done_req = 0; + req->read_is_closed = 0; ++ ++ if(comm_timer_is_set(req->read_again_timer)) ++ comm_timer_disable(req->read_again_timer); + } + + void +diff --git a/services/listen_dnsport.h b/services/listen_dnsport.h +index 963595a1c..79f46705f 100644 +--- a/services/listen_dnsport.h ++++ b/services/listen_dnsport.h +@@ -345,6 +345,10 @@ struct tcp_req_info { + int num_done_req; + /** list of pending writable result packets, malloced one at a time */ + struct tcp_req_done_item* done_req_list; ++ /** the read again timer, when the number of pipelined TCP queries ++ * is large, it waits, zero time, for a new event loop to service ++ * the remainder of the TCP traffic on the fd. */ ++ struct comm_timer* read_again_timer; + }; + + /** +@@ -375,10 +379,12 @@ struct tcp_req_done_item { + * Create tcp request info structure that keeps track of open + * requests on the TCP channel that are resolved at the same time, + * and the pending results that have to get written back to that client. ++ * @param base: comm base for read again timer. + * @param spoolbuf: shared buffer + * @return new structure or NULL on alloc failure. + */ +-struct tcp_req_info* tcp_req_info_create(struct sldns_buffer* spoolbuf); ++struct tcp_req_info* tcp_req_info_create(struct comm_base* base, ++ struct sldns_buffer* spoolbuf); + + /** + * Delete tcp request structure. Called by owning commpoint. +diff --git a/testcode/testbound.c b/testcode/testbound.c +index 063037df4..3a3bcaef6 100644 +--- a/testcode/testbound.c ++++ b/testcode/testbound.c +@@ -786,3 +786,13 @@ size_t doq_table_quic_size_get(struct doq_table* ATTR_UNUSED(table)) + return 0; + } + #endif ++ ++void tcp_read_again_cb(void* ATTR_UNUSED(arg)) ++{ ++ /* nothing */ ++} ++ ++void tcp_more_read_again_cb(void* ATTR_UNUSED(arg)) ++{ ++ /* nothing */ ++} +diff --git a/util/fptr_wlist.c b/util/fptr_wlist.c +index 3c863d5e1..2cf3d320e 100644 +--- a/util/fptr_wlist.c ++++ b/util/fptr_wlist.c +@@ -141,6 +141,8 @@ fptr_whitelist_comm_timer(void (*fptr)(void*)) + #ifdef UB_ON_WINDOWS + else if(fptr == &wsvc_cron_cb) return 1; + #endif ++ else if(fptr == &tcp_read_again_cb) return 1; ++ else if(fptr == &tcp_more_read_again_cb) return 1; + else if(fptr == &auth_xfer_timer) return 1; + else if(fptr == &auth_xfer_probe_timer_callback) return 1; + else if(fptr == &auth_xfer_transfer_timer_callback) return 1; +diff --git a/util/netevent.c b/util/netevent.c +index aedcb5e07..0dde9059c 100644 +--- a/util/netevent.c ++++ b/util/netevent.c +@@ -122,6 +122,10 @@ + #define NUM_UDP_PER_SELECT 1 + #endif + ++/** The number of TCP queries over a TCP connection, per read indication ++ * from select. */ ++#define NUM_TCP_PER_SELECT 100 ++ + /** timeout in millisec to wait for write to unblock, packets dropped after.*/ + #define SEND_BLOCKED_WAIT_TIMEOUT 200 + /** max number of times to wait for write to unblock, packets dropped after.*/ +@@ -4546,6 +4550,10 @@ comm_point_tcp_handle_write(int fd, struct comm_point* c) + static int + tcp_req_info_read_again(int fd, struct comm_point* c) + { ++ /* One event-loop visit drains at most this many pipelined queries; ++ * the rest is re-queued, so that other file descriptors get ++ * serviced in between. */ ++ int budget = NUM_TCP_PER_SELECT; + while(c->tcp_req_info->read_again) { + int r; + c->tcp_req_info->read_again = 0; +@@ -4562,6 +4570,16 @@ tcp_req_info_read_again(int fd, struct comm_point* c) + } + return 0; + } ++ if(--budget <= 0 && c->tcp_req_info->read_again) { ++ /* Defer the rest of the drain to the next loop turn. ++ * This uses a zero delay timer. For TLS the undrained ++ * remainder sits in OpenSSL's user-space buffer. */ ++ struct timeval tv; ++ memset(&tv, 0, sizeof(tv)); ++ verbose(VERB_ALGO, "Defer tcp_req_info read again"); ++ comm_timer_set(c->tcp_req_info->read_again_timer, &tv); ++ return 1; ++ } + } + return 1; + } +@@ -4575,6 +4593,7 @@ tcp_more_read_again(int fd, struct comm_point* c) + /* this continues until the read routines get EAGAIN or so, + * and thus does not call the callback, and the bool is 0 */ + int* moreread = c->tcp_more_read_again; ++ int budget = NUM_TCP_PER_SELECT; + while(moreread && *moreread) { + *moreread = 0; + if(!comm_point_tcp_handle_read(fd, c, 0)) { +@@ -4587,6 +4606,30 @@ tcp_more_read_again(int fd, struct comm_point* c) + } + return; + } ++ if(--budget <= 0 && *moreread) { ++ /* Defer the rest of the drain to the next loop turn. ++ * This uses a zero delay timer. For TLS the undrained ++ * remainder sits in OpenSSL's user-space buffer. */ ++ struct timeval tv; ++ memset(&tv, 0, sizeof(tv)); ++ if(!c->tcp_more_read_again_timer) { ++ c->tcp_more_read_again_timer = comm_timer_create(c->ev->base, tcp_more_read_again_cb, c); ++ if(!c->tcp_more_read_again_timer) { ++ log_err("out of memory for tcp more read again timer"); ++ reclaim_tcp_handler(c); ++ if(!c->tcp_do_close) { ++ fptr_ok(fptr_whitelist_comm_point( ++ c->callback)); ++ (void)(*c->callback)(c, c->cb_arg, ++ NETEVENT_CLOSED, NULL); ++ } ++ return; ++ } ++ } ++ verbose(VERB_ALGO, "Defer more read again"); ++ comm_timer_set(c->tcp_more_read_again_timer, &tv); ++ return; ++ } + } + } + +@@ -4614,6 +4657,23 @@ tcp_more_write_again(int fd, struct comm_point* c) + } + } + ++void ++tcp_read_again_cb(void* arg) ++{ ++ struct tcp_req_info* req = (struct tcp_req_info*)arg; ++ verbose(VERB_ALGO, "tcp_read_again_cb"); ++ if(!tcp_req_info_read_again(req->cp->fd, req->cp)) ++ return; ++} ++ ++void ++tcp_more_read_again_cb(void* arg) ++{ ++ struct comm_point* c = (struct comm_point*)arg; ++ verbose(VERB_ALGO, "tcp_more_read_again_cb"); ++ tcp_more_read_again(c->fd, c); ++} ++ + void + comm_point_tcp_handle_callback(int fd, short event, void* arg) + { +@@ -6025,7 +6085,7 @@ comm_point_create_tcp_handler(struct comm_base *base, + c->pp2_enabled = parent->pp2_enabled; + c->pp2_header_state = pp2_header_none; + if(spoolbuf) { +- c->tcp_req_info = tcp_req_info_create(spoolbuf); ++ c->tcp_req_info = tcp_req_info_create(base, spoolbuf); + if(!c->tcp_req_info) { + log_err("could not create tcp commpoint"); + sldns_buffer_free(c->buffer); +@@ -6584,6 +6644,9 @@ comm_point_close(struct comm_point* c) + *c->tcp_more_read_again = 0; + if(c->tcp_more_write_again && *c->tcp_more_write_again) + *c->tcp_more_write_again = 0; ++ if(c->tcp_more_read_again_timer && ++ comm_timer_is_set(c->tcp_more_read_again_timer)) ++ comm_timer_disable(c->tcp_more_read_again_timer); + + /* close fd after removing from event lists, or epoll.. is messed up */ + if(c->fd != -1 && !c->do_not_close) { +@@ -6623,6 +6686,7 @@ comm_point_delete(struct comm_point* c) + free(c->tcp_handlers); + } + free(c->timeout); ++ comm_timer_delete(c->tcp_more_read_again_timer); + if(c->type == comm_tcp || c->type == comm_local || c->type == comm_http) { + sldns_buffer_free(c->buffer); + #ifdef USE_DNSCRYPT +diff --git a/util/netevent.h b/util/netevent.h +index c5114bbbe..dae2c375a 100644 +--- a/util/netevent.h ++++ b/util/netevent.h +@@ -380,6 +380,9 @@ struct comm_point { + * Or leave NULL if it is not used at all. */ + int* tcp_more_write_again; + ++ /** resume timer for tcp_more_read_again */ ++ struct comm_timer* tcp_more_read_again_timer; ++ + /** if set, read/write completes: + read/write state of tcp is toggled. + buffer reset/bytecount reset. +@@ -1127,6 +1130,12 @@ void doq_send_pkt(struct comm_point* c, struct doq_pkt_addr* paddr, + /** doq timer callback function. */ + void doq_timer_cb(void* arg); + ++/** tcp read again callback function. For tcp req info listen. */ ++void tcp_read_again_cb(void* arg); ++ ++/** tcp more read again callback function. For outside network. */ ++void tcp_more_read_again_cb(void* arg); ++ + /** + * This routine is published for checks and tests, and is only used internally. + * handle libevent callback for timer comm. 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 faf315876c..0b59d7c9f9 100644 --- a/meta-networking/recipes-support/unbound/unbound_1.24.2.bb +++ b/meta-networking/recipes-support/unbound/unbound_1.24.2.bb @@ -43,6 +43,7 @@ SRC_URI = "git://github.com/NLnetLabs/unbound.git;protocol=https;branch=master;t file://CVE-2026-55991.patch \ file://CVE-2026-56416.patch \ file://CVE-2026-56444.patch \ + file://CVE-2026-80225.patch \ " SRCREV = "f6269baa605d31859f28770e01a24e3677e5f82c"