From bf9fd650883b23604b7cd4aabf04fc0c4c8fe7c7 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Thu, 2 Aug 2018 11:05:48 +0200 Subject: [PATCH] BUG/MEDIUM: cli: make "show fd" thread-safe The "show fd" command was implemented as a debugging aid but it's not thread safe. Its features have grown, it can now dump some mux-specific parts and is being used in production to capture some useful debugging traces. But it will quickly crash the process when used during an H2 load test for example, especially when haproxy is built with the DEBUG_UAF option. It cannot afford not to be thread safe anymore. Let's make use of the new rendez-vous point using thread_isolate() / thread_release() to ensure that the data being dumped are not changing under us. The dump becomes slightly slower under load but now it's safe. This should be backported to 1.8 along with the rendez-vous point code once considered stable enough. --- src/cli.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/cli.c b/src/cli.c index 739107dab..ce8635f2b 100644 --- a/src/cli.c +++ b/src/cli.c @@ -847,10 +847,14 @@ static int cli_io_handler_show_fd(struct appctx *appctx) void *ctx = NULL; uint32_t conn_flags = 0; + thread_isolate(); + fdt = fdtab[fd]; - if (!fdt.owner) + if (!fdt.owner) { + thread_release(); goto skip; // closed + } if (fdt.iocb == conn_fd_handler) { conn_flags = ((struct connection *)fdt.owner)->flags; @@ -916,6 +920,8 @@ static int cli_io_handler_show_fd(struct appctx *appctx) li->bind_conf->frontend->id); } + thread_release(); + chunk_appendf(&trash, "\n"); if (ci_putchk(si_ic(si), &trash) == -1) {