From: Willy Tarreau Date: Fri, 17 Oct 2025 18:36:00 +0000 (+0200) Subject: BUG/MEDIUM: threads/config: drop absent threads from thread groups X-Git-Tag: v3.3-dev10~2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c365e47095495ddf33ee7ae4f010f3cf5ef71bfc;p=thirdparty%2Fhaproxy.git BUG/MEDIUM: threads/config: drop absent threads from thread groups Thread groups can be assigned arbitrary thread ranges, but if the mentioned threads do not exist, this causes crashes in listener_accept() or some connections to be ignored. The reason is that the calculated mask is derived from the thread group's enabled threads count. Examples: global nbthread 2 thread-groups 2 thread-group 1 1-64 thread-group 2 65-128 frontend f-crash bind :8001 thread 1/all frontend f-freeze bind :8002 thread 2/all This commit removes missing threads, emits a warning when the thread group just has less threads than requested, and an error when it is left with no threads at all. This must be backported to 3.1 since the issue is present there already. --- diff --git a/src/thread.c b/src/thread.c index 02929916c..b5f5d7d97 100644 --- a/src/thread.c +++ b/src/thread.c @@ -1459,6 +1459,23 @@ int thread_map_to_groups() ha_thread_info[t].ltid_bit = 1UL << ha_thread_info[t].ltid; } + /* limit thread groups to existing threads only */ + for (g = 0; g < global.nbtgroups; g++) { + if (ha_tgroup_info[g].base >= global.nbthread) { + ha_alert("Thread-group %d only references non-existing threads (max=%d, requested %d-%d)\n", + g + 1, global.nbthread, ha_tgroup_info[g].base + 1, ha_tgroup_info[g].base + ha_tgroup_info[g].count); + return -1; + } + + if (ha_tgroup_info[g].base + ha_tgroup_info[g].count > global.nbthread) { + ha_warning("Reducing thread-group %d to %d threads (requested %d-%d, using %d-%d)\n", + g + 1, global.nbthread - ha_tgroup_info[g].base, + ha_tgroup_info[g].base + 1, ha_tgroup_info[g].base + ha_tgroup_info[g].count, + ha_tgroup_info[g].base + 1, global.nbthread); + ha_tgroup_info[g].count = global.nbthread - ha_tgroup_info[g].base; + } + } + m = 0; for (g = 0; g < global.nbtgroups; g++) { ha_tgroup_info[g].threads_enabled = nbits(ha_tgroup_info[g].count);