From: Amaury Denoyelle Date: Fri, 30 Oct 2026 09:53:08 +0000 (+0100) Subject: BUG/MINOR: debug: fix "debug dev fd" crash on unknown address families X-Git-Tag: v3.5-dev11~88 X-Git-Url: https://git.kaiwu.me/?a=commitdiff_plain;h=21a17a5c4ab354e16592e42860238d36decd8648;p=haproxy.git BUG/MINOR: debug: fix "debug dev fd" crash on unknown address families "debug dev fd" formats the local and peer addresses of each fd with sa2str() and then replaces non-printable characters in the result. It returns NULL for address families other than AF_INET, AF_INET6, AF_UNIX and some AF_CUST_*. For supported address families, it can also return NULL in case of a memory allocation failure. Only an admin in expert mode can run the command. Let's skip the cleanup and print "?" when sa2str() fails. This fixes GitHub issue #3546. This must be backported to all stable versions. In fact, strlen() without guard was introduced in 3.1, which guarantees a crash in case of an unsupported address. For older releases, only an unsafe chunk_appendf() is present which may cause issues. --- diff --git a/src/debug.c b/src/debug.c index bc6355e12..69c1383b6 100644 --- a/src/debug.c +++ b/src/debug.c @@ -2304,13 +2304,18 @@ static int debug_iohandler_fd(struct appctx *appctx) port = 0; addrstr = sa2str(&sa, port, 0); /* cleanup the output */ - for (i = 0; i < strlen(addrstr); i++) { - if (iscntrl((unsigned char)addrstr[i]) || !isprint((unsigned char)addrstr[i])) - addrstr[i] = '.'; - } + if (addrstr) { + for (i = 0; i < strlen(addrstr); i++) { + if (iscntrl((unsigned char)addrstr[i]) || !isprint((unsigned char)addrstr[i])) + addrstr[i] = '.'; + } - chunk_appendf(&trash, " laddr=%s", addrstr); - free(addrstr); + chunk_appendf(&trash, " laddr=%s", addrstr); + free(addrstr); + } + else { + chunk_appendf(&trash, " laddr=?"); + } } salen = sizeof(sa); @@ -2323,12 +2328,17 @@ static int debug_iohandler_fd(struct appctx *appctx) port = 0; addrstr = sa2str(&sa, port, 0); /* cleanup the output */ - for (i = 0; i < strlen(addrstr); i++) { - if ((iscntrl((unsigned char)addrstr[i])) || !isprint((unsigned char)addrstr[i])) - addrstr[i] = '.'; + if (addrstr) { + for (i = 0; i < strlen(addrstr); i++) { + if ((iscntrl((unsigned char)addrstr[i])) || !isprint((unsigned char)addrstr[i])) + addrstr[i] = '.'; + } + chunk_appendf(&trash, " raddr=%s", addrstr); + free(addrstr); + } + else { + chunk_appendf(&trash, " raddr=?"); } - chunk_appendf(&trash, " raddr=%s", addrstr); - free(addrstr); } chunk_appendf(&trash, "\n");