unbound: patch CVE-2026-52863

Details:
https://nvd.nist.gov/vuln/detail/cve-2026-52863

Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com>
Signed-off-by: Anuj Mittal <anuj.mittal@oss.qualcomm.com>
This commit is contained in:
Ankur Tyagi
2026-09-15 10:14:01 +05:30
committed by Anuj Mittal
parent 9cf83c6ad4
commit e88cf8a339
2 changed files with 133 additions and 0 deletions
@@ -0,0 +1,132 @@
From da55f7d129bfa01201d8e2bb58b13674f41c572e Mon Sep 17 00:00:00 2001
From: "W.C.A. Wijngaards" <wouter@nlnetlabs.nl>
Date: Wed, 22 Jul 2026 10:16:03 +0200
Subject: [PATCH] - Fix CVE-2026-52863, Memory corruption could lead to crash
and denial of service. Thanks to Qifan Zhang, Palo Alto Networks, for the
report.
(cherry picked from commit 8c702de175cb687d9645603ad3e8dc7c08a925e8)
CVE: CVE-2026-52863
Upstream-Status: Backport [https://github.com/NLnetLabs/unbound/commit/8c702de175cb687d9645603ad3e8dc7c08a925e8]
Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com>
---
services/mesh.c | 8 +++++--
services/mesh.h | 4 ++++
testcode/unitmain.c | 56 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 66 insertions(+), 2 deletions(-)
diff --git a/services/mesh.c b/services/mesh.c
index 23499dcef..6a04bc838 100644
--- a/services/mesh.c
+++ b/services/mesh.c
@@ -911,8 +911,7 @@ cfg_region_strlist_copy(struct regional* region, struct config_strlist* list)
return result;
}
-/** Copy the client info to the query region. */
-static struct respip_client_info*
+struct respip_client_info*
mesh_copy_client_info(struct regional* region, struct respip_client_info* cinfo)
{
size_t i;
@@ -957,6 +956,11 @@ mesh_copy_client_info(struct regional* region, struct respip_client_info* cinfo)
cinfo->view->name);
if(!client_info->view_name)
return NULL;
+ } else if(cinfo->view_name) {
+ client_info->view_name = regional_strdup(region,
+ cinfo->view_name);
+ if(!client_info->view_name)
+ return NULL;
}
return client_info;
}
diff --git a/services/mesh.h b/services/mesh.h
index a61f90993..b3e1f0efa 100644
--- a/services/mesh.h
+++ b/services/mesh.h
@@ -729,4 +729,8 @@ void mesh_respond_serve_expired(struct mesh_state* mstate);
void mesh_remove_callback(struct mesh_area* mesh, struct query_info* qinfo,
uint16_t qflags, mesh_cb_func_type cb, void* cb_arg);
+/** Copy the client info to the query region. */
+struct respip_client_info* mesh_copy_client_info(struct regional* region,
+ struct respip_client_info* cinfo);
+
#endif /* SERVICES_MESH_H */
diff --git a/testcode/unitmain.c b/testcode/unitmain.c
index beb10ba45..edde04875 100644
--- a/testcode/unitmain.c
+++ b/testcode/unitmain.c
@@ -1282,6 +1282,61 @@ static void localzone_test(void)
localzone_parents_test();
}
+#include "services/mesh.h"
+/** mesh unit tests */
+static void mesh_test(void)
+{
+ struct regional* r2, *r3;
+ struct respip_client_info* c1, *c2, *c3;
+ unit_show_func("services/mesh.c", "mesh_copy_client_info");
+ r2 = regional_create();
+ r3 = regional_create();
+ if(!r2 || !r3) fatal_exit("out of memory");
+
+ c1 = calloc(1, sizeof(*c1));
+ if(!c1) fatal_exit("out of memory");
+ c1->view = calloc(1, sizeof(*c1->view));
+ if(!c1->view) fatal_exit("out of memory");
+ c1->view->name = strdup("view1");
+ if(!c1->view->name) fatal_exit("out of memory");
+
+ c2 = mesh_copy_client_info(r2, c1);
+ if(!c2) fatal_exit("out of memory");
+ c3 = mesh_copy_client_info(r3, c2);
+ if(!c3) fatal_exit("out of memory");
+
+ unit_assert(strcmp(c1->view->name, c2->view_name) == 0);
+ unit_assert(strcmp(c1->view->name, c3->view_name) == 0);
+
+ /* make sure that the c3 view_name is in the r3 region. */
+ unit_assert(r3->next == NULL); /* only the first chunk present atm */
+ if(strlen(c3->view_name) >= r3->large_object_size) {
+ char* a = r3->large_list;
+ int found = 0;
+ while(a) {
+ if(strcmp(c3->view_name,
+ a + /* ALIGNEMENT */ sizeof(uint64_t)) == 0) {
+ found = 1;
+ break;
+ }
+ a = *(char**)a;
+ }
+ unit_assert(found == 1);
+ } else {
+ /* The allocation is expected in the r3 region first chunk */
+ unit_assert((uint8_t*)c3->view_name < ((uint8_t*)r3)+r3->first_size);
+ }
+
+ regional_destroy(r2);
+ /* ASAN should complain for the freed access below */
+ unit_assert(strcmp(c1->view->name, c3->view_name) == 0);
+
+ regional_destroy(r3);
+ free(c1->view->name);
+ free(c1->view);
+ free(c1);
+}
+
void unit_show_func(const char* file, const char* func)
{
printf("test %s:%s\n", file, func);
@@ -1356,6 +1411,7 @@ main(int argc, char* argv[])
msgparse_test();
edns_ede_answer_encode_test();
localzone_test();
+ mesh_test();
#ifdef CLIENT_SUBNET
ecs_test();
#endif /* CLIENT_SUBNET */
@@ -34,6 +34,7 @@ SRC_URI = "git://github.com/NLnetLabs/unbound.git;protocol=https;branch=master;t
file://CVE-2026-50248.patch \
file://CVE-2026-50251.patch \
file://CVE-2026-50252.patch \
file://CVE-2026-52863.patch \
"
SRCREV = "f6269baa605d31859f28770e01a24e3677e5f82c"