From: W.C.A. Wijngaards Date: Wed, 20 May 2026 08:19:08 +0000 (+0200) Subject: - Fix CVE-2026-42534, Jostle logic bypass degrades resolution X-Git-Tag: release-1.25.1~5 X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=a794c87578c963606a6fb00a54c46fcf935f519a;p=thirdparty%2Funbound.git - Fix CVE-2026-42534, Jostle logic bypass degrades resolution performance. Thanks to Qifan Zhang, Palo Alto Networks, for the report. --- diff --git a/doc/Changelog b/doc/Changelog index c823bcbd2..03fa7ed3a 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -13,6 +13,9 @@ - Fix CVE-2026-41292, Parsing a long list of incoming EDNS options degrades performance. Thanks to GitHub user 'N0zoM1z0', also Qifan Zhang from Palo Alto Networks, for the report. + - Fix CVE-2026-42534, Jostle logic bypass degrades resolution + performance. Thanks to Qifan Zhang, Palo Alto Networks, for the + report. 23 April 2026: Wouter - Merge #1441: Fix buffer overrun in diff --git a/services/mesh.c b/services/mesh.c index 433aabc9c..286901047 100644 --- a/services/mesh.c +++ b/services/mesh.c @@ -297,12 +297,14 @@ int mesh_make_new_space(struct mesh_area* mesh, sldns_buffer* qbuf) if(mesh->num_reply_states < mesh->max_reply_states) return 1; /* try to kick out a jostle-list item */ - if(m && m->reply_list && m->list_select == mesh_jostle_list) { + if(m && m->list_select == mesh_jostle_list) { /* how old is it? */ struct timeval age; - timeval_subtract(&age, mesh->env->now_tv, - &m->reply_list->start_time); - if(timeval_smaller(&mesh->jostle_max, &age)) { + if(m->has_first_reply_time) + timeval_subtract(&age, mesh->env->now_tv, + &m->first_reply_time); + if(!m->has_first_reply_time || + timeval_smaller(&mesh->jostle_max, &age)) { /* its a goner */ log_nametypeclass(VERB_ALGO, "query jostled out to " "make space for a new one", @@ -1995,6 +1997,10 @@ int mesh_state_add_reply(struct mesh_state* s, struct edns_data* edns, r->qid = qid; r->qflags = qflags; r->start_time = *s->s.env->now_tv; + if(s->reply_list == NULL && !s->has_first_reply_time) { + s->first_reply_time = r->start_time; + s->has_first_reply_time = 1; + } r->next = s->reply_list; r->qname = regional_alloc_init(s->s.region, qinfo->qname, s->s.qinfo.qname_len); diff --git a/services/mesh.h b/services/mesh.h index d2fac9d3c..9ee585156 100644 --- a/services/mesh.h +++ b/services/mesh.h @@ -191,6 +191,12 @@ struct mesh_state { struct module_qstate s; /** the list of replies to clients for the results */ struct mesh_reply* reply_list; + /** if it has a first reply time */ + int has_first_reply_time; + /** wall-clock time the first client reply was attached; + * used by mesh_make_new_space() so duplicate retransmits + * cannot reset jostle aging. */ + struct timeval first_reply_time; /** the list of callbacks for the results */ struct mesh_cb* cb_list; /** set of superstates (that want this state's result)