]> git.kaiwu.me - haproxy.git/commitdiff
BUG/MINOR: tools: make strl2irc() and strl2llrc() reject a lone minus sign
authorMartin Mirchev <mmirchev@comp.nus.edu.sg>
Tue, 27 Oct 2026 03:36:58 +0000 (11:36 +0800)
committerWilly Tarreau <w@1wt.eu>
Wed, 28 Oct 2026 10:38:26 +0000 (11:38 +0100)
strl2irc() and strl2llrc() are documented to accurately detect any error
(truncated string, invalid chars, overflows). But when the string is made
of a single '-', the negative branch skips the sign, the digit loop does not
run since there is nothing left, and the function returns success with 0.

As a result, a lone "-" is silently taken as 0 wherever these functions are
used to validate a number:
  - "uid -" and "gid -" in the global section set uid/gid 0 (root)
    instead of emitting the usual "is not a number" warning. When started
    as root, this also suppresses the warning about running as root
    without "user"/"uid", so the process silently keeps root privileges;
  - "set server <b>/<s> check-port -" (and "agent-port -") on the CLI
    sets port 0 instead of failing with "provided port is not an
    integer";
  - req.hdr_ip() accepts "1.2.3.4:-" as a valid address and port;
  - an integer ACL pattern ":-" is taken as ":0", and a "-" value in the
    CLI "set table ... data.<type> -" command stores 0.

Let's return an error when the sign is not followed by any digit. A
reg-test checks that "uid -" and "gid -" now produce the warning (made
fatal with -dW).

This has been there since the functions were introduced, so the fix may be
backported to all stable branches.
[wt: better not backport as it could break configs running by accident]

src/tools.c

index 16936985b28c72ca99d9d243196786b43b47c8da..11ad0f03a96a8fd787189d07519ae40bd9e7af05 100644 (file)
@@ -2821,6 +2821,8 @@ int strl2irc(const char *s, int len, int *ret)
                }
        } else {
                /* negative number */
+               if (len == 1)
+                       return 1; /* sign alone, no digit */
                s++;
                while (--len > 0) {
                        j = (*s++) - '0';
@@ -2865,6 +2867,8 @@ int strl2llrc(const char *s, int len, long long *ret)
                }
        } else {
                /* negative number */
+               if (len == 1)
+                       return 1; /* sign alone, no digit */
                s++;
                while (--len > 0) {
                        j = (*s++) - '0';