]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: trace: stop rewriting argv with -dt
authorWilliam Lallemand <wlallemand@haproxy.com>
Tue, 29 Oct 2024 09:50:27 +0000 (10:50 +0100)
committerWilliam Lallemand <wlallemand@haproxy.com>
Tue, 29 Oct 2024 10:01:47 +0000 (11:01 +0100)
When using trace with -dt, the trace_parse_cmd() function is doing a
strtok which write \0 into the argv string.

When using the mworker mode, and reloading, argv was modified and the
trace won't work anymore because the first : is replaced by a '\0'.

This patch fixes the issue by allocating a temporary string so we don't
modify the source string directly. It also replace strtok by its
reentrant version strtok_r.

Must be backported as far as 2.9.

include/haproxy/trace.h
src/trace.c

index f6749160ceae5ddc9a59324bc411142a90c4272b..ce94289154965e5f5153a4e06bc54ae45ce389f0 100644 (file)
@@ -190,7 +190,7 @@ void trace_no_cb(enum trace_level level, uint64_t mask, const struct trace_sourc
 
 void trace_register_source(struct trace_source *source);
 
-int trace_parse_cmd(char *arg, char **errmsg);
+int trace_parse_cmd(const char *arg_src, char **errmsg);
 
 /* return a single char to describe a trace state */
 static inline char trace_state_char(enum trace_state st)
index 95ec6aa2e572c54035d82f77b6169c4acdfd81a0..cc49ed98b1cae6c26472526aeb9949584ea68aa4 100644 (file)
@@ -966,11 +966,22 @@ void _trace_parse_cmd(struct trace_source *src, int level, int verbosity)
  *
  * Returns 0 on success else non-zero.
  */
-int trace_parse_cmd(char *arg, char **errmsg)
+int trace_parse_cmd(const char *arg_src, char **errmsg)
 {
        char *str;
+       char *arg, *oarg;
+       char *saveptr;
+
+       if (arg_src) {
+               /* keep a copy of the ptr for strtok */
+               oarg = arg = strdup(arg_src);
+               if (!arg) {
+                       memprintf(errmsg, "Can't allocate !");
+                       return 1;
+               }
+       }
 
-       if (!arg) {
+       if (!arg_src) {
                /* No trace specification, activate all sources on error level. */
                struct trace_source *src = NULL;
 
@@ -979,7 +990,7 @@ int trace_parse_cmd(char *arg, char **errmsg)
                return 0;
        }
 
-       while ((str = strtok(arg, ","))) {
+       while ((str = strtok_r(arg, ",", &saveptr))) {
                struct trace_source *src = NULL;
                char *field, *name;
                char *sep;
@@ -1000,6 +1011,7 @@ int trace_parse_cmd(char *arg, char **errmsg)
                        src = trace_find_source(name);
                        if (!src) {
                                memprintf(errmsg, "unknown trace source '%s'", name);
+                               ha_free(&oarg);
                                return 1;
                        }
                }
@@ -1022,6 +1034,7 @@ int trace_parse_cmd(char *arg, char **errmsg)
                        level = trace_parse_level(field);
                        if (level < 0) {
                                memprintf(errmsg, "no such trace level '%s', available levels are 'error', 'user', 'proto', 'state', 'data', and 'developer'", field);
+                               ha_free(&oarg);
                                return 1;
                        }
                }
@@ -1033,6 +1046,7 @@ int trace_parse_cmd(char *arg, char **errmsg)
                field = str;
                if (strchr(field, ':')) {
                        memprintf(errmsg, "too many double-colon separators in trace definition");
+                       ha_free(&oarg);
                        return 1;
                }
 
@@ -1049,6 +1063,7 @@ int trace_parse_cmd(char *arg, char **errmsg)
                                        memprintf(errmsg, "%s, %s'%s'", *errmsg, (nd + 1)->name ? "" : "and ", nd->name);
                        }
 
+                       ha_free(&oarg);
                        return 1;
                }
 
@@ -1064,7 +1079,7 @@ int trace_parse_cmd(char *arg, char **errmsg)
                /* Reset arg to NULL for strtok. */
                arg = NULL;
        }
-
+       ha_free(&oarg);
        return 0;
 }