From: Amaury Denoyelle Date: Tue, 21 Jul 2026 07:26:22 +0000 (+0200) Subject: BUG/MEDIUM: proxy: protect "show servers ..." against server deletion X-Git-Tag: v3.5-dev3~6 X-Git-Url: http://git.kaiwu.me/http/$%7BGITURL%7D/%22data:,/$%7BGITURL%7D$%7Bcid%7D?a=commitdiff_plain;h=282ac06d81462b0f78fb5cf7972ab567b123e575;p=haproxy.git BUG/MEDIUM: proxy: protect "show servers ..." against server deletion Command show servers conn/state loops over a server list to display various information. This command may yield in case of a large output. This can cause a crash if the server on which the command was paused is deleted prior to restarting the command. Fixes this by using the watcher mechanism, similar to what is already implementing with stats dump. This must be backported at least up to 3.0. For older releases, watcher mechanism is not available, server refcount + SRV_F_DELETED flag must be used instead. --- diff --git a/src/proxy.c b/src/proxy.c index 8592e409a..783998939 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -92,6 +92,8 @@ struct show_srv_ctx { SHOW_SRV_HEAD = 0, SHOW_SRV_LIST, } state; + + struct watcher srv_watch; /* watcher to automatically update sv on server deletion */ }; /* proxy->options. For unsupported ones, pass 0 in the "cap" (PR_CAP_*) field. @@ -4438,6 +4440,7 @@ static int cli_parse_show_servers(char **args, char *payload, struct appctx *app struct proxy *px; ctx->show_conn = *args[2] == 'c'; // "conn" vs "state" + watcher_init(&ctx->srv_watch, &ctx->sv, offsetof(struct server, watcher_list)); /* check if a backend name has been provided */ if (*args[3]) { @@ -4489,9 +4492,9 @@ static int dump_servers_state(struct appctx *appctx) char *srvrecord; if (!ctx->sv) - ctx->sv = px->srv; + watcher_attach(&ctx->srv_watch, px->srv); - for (; ctx->sv != NULL; ctx->sv = srv->next) { + for (; ctx->sv; watcher_next(&ctx->srv_watch, ctx->sv->next)) { srv = ctx->sv; dump_server_addr(&srv->addr, srv_addr);