From: Willy Tarreau Date: Mon, 3 Oct 2022 06:27:55 +0000 (+0200) Subject: BUG/MEDIUM: config: count line arguments without dereferencing the output X-Git-Tag: v2.7-dev7~4 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=94ab139266a2d2d39f7254644f69fb699559e8e2;p=thirdparty%2Fhaproxy.git BUG/MEDIUM: config: count line arguments without dereferencing the output Previous commit 8a6767d26 ("BUG/MINOR: config: don't count trailing spaces as empty arg (v2)") was still not enough. As reported by ClusterFuzz in issue 52049 (https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=52049), there remains a case where for the sake of reporting the correct argument count, the function may produce virtual args that span beyond the end of the output buffer if that one is too short. That's what's happening with a config file of one empty line followed by a large number of args. This means that what args[] points to cannot be relied on and that a different approach is needed. Since no output is produced for spaces and comments, we know that args[arg] continues to point to out+outpos as long as only comments or spaces are found, which is what we're interested in. As such it's safe to check the last arg's pointer against the one before the trailing zero was emitted, in order to decide to count one final arg. No backport is needed, unless the commit above is backported. --- diff --git a/src/tools.c b/src/tools.c index 3796c98b11..5f44a2f0c7 100644 --- a/src/tools.c +++ b/src/tools.c @@ -5751,11 +5751,12 @@ uint32_t parse_line(char *in, char *out, size_t *outlen, char **args, int *nbarg /* end of output string */ EMIT_CHAR(0); - /* don't add empty arg after trailing spaces. Note that args[arg] - * may contain some distances relative to NULL if was NULL, - * so we test instead of args[arg]. + /* Don't add an empty arg after trailing spaces. Note that args[arg] + * may contain some distances relative to NULL if was NULL, or + * pointers beyond the end of in case is too short, thus + * we must not dereference it. */ - if (arg < argsmax && out && *(args[arg])) + if (arg < argsmax && args[arg] != out + outpos - 1) arg++; if (quote) {