]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: proxy: protect "show errors" against backend deletion
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Thu, 23 Jul 2026 09:28:07 +0000 (11:28 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Thu, 23 Jul 2026 12:20:18 +0000 (14:20 +0200)
Command "show errors" is not safe as it loops over the list of proxies.
A crash may occur if the task yields on a proxy which is deleted just
before the dump is restarted.

As with previous fixes dealing with similar cases, this is fixed via the
watcher mechanism. A new <px_watcher> member is defined in
<show_errors_ctx> and used to loop over the proxies list.

This must be backported up to 3.4.

src/proxy.c

index e69d8afddbba161798521862bf7545968660f280..85878f9b8b840362a01d82f9257baf68e3786785 100644 (file)
@@ -5260,6 +5260,8 @@ struct show_errors_ctx {
        int iid;                /* if >= 0, ID of the proxy to filter on */
        int ptr;                /* <0: headers, >=0 : text pointer to restart from */
        int bol;                /* pointer to beginning of current line */
+
+       struct watcher px_watch; /* watcher to automatically update px pointer on backend deletion */
 };
 
 /* "show errors" handler for the CLI. Returns 0 if wants to continue, 1 to stop
@@ -5292,7 +5294,10 @@ static int cli_parse_show_errors(char **args, char *payload, struct appctx *appc
                ctx->flag |= 4; // ignore response
        else if (strcmp(args[3], "response") == 0)
                ctx->flag |= 2; // ignore request
+
        ctx->px = NULL;
+       watcher_init(&ctx->px_watch, &ctx->px, offsetof(struct proxy, watcher_list));
+
        return 0;
 }
 
@@ -5322,7 +5327,7 @@ static int cli_io_handler_show_errors(struct appctx *appctx)
                if (applet_putchk(appctx, &trash) == -1)
                        goto cant_send;
 
-               ctx->px = proxies_list;
+               watcher_attach(&ctx->px_watch, proxies_list);
                ctx->bol = 0;
                ctx->ptr = -1;
        }
@@ -5450,7 +5455,7 @@ static int cli_io_handler_show_errors(struct appctx *appctx)
                ctx->ptr = -1;
                ctx->flag ^= 1;
                if (!(ctx->flag & 1))
-                       ctx->px = ctx->px->next;
+                       watcher_next(&ctx->px_watch, ctx->px->next);
        }
 
        /* dump complete */