From: William Lallemand Date: Wed, 20 Jul 2022 22:52:43 +0000 (+0200) Subject: BUG/MEDIUM: mworker: proc_self incorrectly set crashes upon reload X-Git-Tag: v2.7-dev3~74 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d4835a9680126f0059349fc7d81b741dc29a7428;p=thirdparty%2Fhaproxy.git BUG/MEDIUM: mworker: proc_self incorrectly set crashes upon reload When updating from 2.4 to 2.6, the child->reloads++ instruction changed place, resulting in a former worker from the 2.4 process, still identified as a current worker once in 2.6, because its reload counter is still 0. Unfortunately this counter is used to chose the mworker_proc structure that will be used for the new worker. What happens next, is that the mworker_proc structure of the previous process is selected, and this one has ipc_fd[1] set to -1, because this structure was supposed to be in the master. The process then forks, and mworker_sockpair_register_per_thread() tries to register ipc_fd[1] which is set to -1, instead of the fd of the new socketpair. This patch fixes the issue by checking if child->pid is equal to -1 when selecting proc_self. This way we could be sure it wasn't a previous process. Should fix issue #1785. This must be backported as far as 2.4 to fix the issue related to the reload computation difference. However backporting it in every stable branch will enforce the reload process. --- diff --git a/src/haproxy.c b/src/haproxy.c index 1d0fa33682..9ec9639030 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -3388,7 +3388,9 @@ int main(int argc, char **argv) ha_notice("New worker (%d) forked\n", ret); /* find the right mworker_proc */ list_for_each_entry(child, &proc_list, list) { - if (child->reloads == 0 && child->options & PROC_O_TYPE_WORKER) { + if (child->reloads == 0 && + child->options & PROC_O_TYPE_WORKER && + child->pid == -1) { child->timestamp = now.tv_sec; child->pid = ret; child->version = strdup(haproxy_version); @@ -3482,7 +3484,8 @@ int main(int argc, char **argv) child->ipc_fd[0] = -1; } if (child->options & PROC_O_TYPE_WORKER && - child->reloads == 0) { + child->reloads == 0 && + child->pid == -1) { /* keep this struct if this is our pid */ proc_self = child; continue;