]> git.kaiwu.me - haproxy.git/commitdiff
BUG/MINOR: debug: fix "debug dev fd" crash on unknown address families
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Fri, 30 Oct 2026 09:53:08 +0000 (10:53 +0100)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Fri, 30 Oct 2026 13:04:04 +0000 (14:04 +0100)
"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.

src/debug.c

index bc6355e12424cabd5c9e8deb2fdbecc11aa4031b..69c1383b69b4a92fca98bcd583160af491b6e69b 100644 (file)
@@ -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");