]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: cfgparse: consider the special case of empty arg caused by \x00
authorWilly Tarreau <w@1wt.eu>
Fri, 9 May 2025 07:55:39 +0000 (09:55 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 9 May 2025 08:01:44 +0000 (10:01 +0200)
The reporting of the empty arg location added with commit 08d3caf30
("MINOR: cfgparse: visually show the input line on empty args") falls
victim of a special case detected by OSS Fuzz:

     https://issues.oss-fuzz.com/issues/415850462

In short, making an argument start with "\x00" doesn't make it empty for
the parser, but still emits an empty string which is detected and
displayed. Unfortunately in this case the error pointer is not set so
the sanitization function crashes.

What we're doing in this case is that we fall back to the position of
the output argument as an estimate of where it was located in the input.
It's clearly inexact (quoting etc) but will still help the user locate
the problem.

No backport is needed unless the commit above is backported.

src/cfgparse.c

index 3421a09971e30f37a43f3f1c405206cbc9276ff8..1fea159151a78593447e9a11a0cf66274774f13d 100644 (file)
@@ -1981,7 +1981,7 @@ next_line:
 
                while (1) {
                        uint32_t err;
-                       const char *errptr;
+                       const char *errptr = NULL;
                        int check_arg;
 
                        arg = sizeof(args) / sizeof(*args);
@@ -2067,9 +2067,16 @@ next_line:
 
                        for (check_arg = 0; check_arg < arg; check_arg++) {
                                if (!*args[check_arg]) {
-                                       /* if an empty arg was found, its pointer is in <errptr> */
                                        size_t newpos;
 
+                                       /* if an empty arg was found, its pointer should be in <errptr>, except
+                                        * for rare cases such as '\x00' etc. We need to check errptr in any case
+                                        * and if it's not set, we'll fall back to args's position in the output
+                                        * string instead (less accurate but still useful).
+                                        */
+                                       if (!errptr)
+                                               errptr = args[check_arg] - outline + line;
+
                                        /* sanitize input line in-place */
                                        newpos = sanitize_for_printing(line, errptr - line, 80);
                                        ha_warning("parsing [%s:%d]: argument number %d at position %d is empty and marks the end of the "