]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: mcli: always realign wrapping buffers before parsing them
authorWilly Tarreau <w@1wt.eu>
Thu, 20 Jan 2022 07:47:35 +0000 (08:47 +0100)
committerWilly Tarreau <w@1wt.eu>
Thu, 20 Jan 2022 17:56:57 +0000 (18:56 +0100)
Pipelined commands easily result in request buffers to wrap, and the
master-cli parser only deals with linear buffers since it needs contiguous
keywords to look for in a list. As soon as a buffer wraps, some commands
are ignored and the parser is called in loops because the wrapped data
do not leave the buffer.

Let's take the easiest path that's already used at the HTTP layer, we
simply realign the buffer if its input wraps. This rarely happens anyway
(typically once per buffer), remains reasonably cheap and guarantees this
cannot happen anymore.

This needs to be backported as far as 2.0.

src/cli.c

index 3744ac3acc6484290f4c0cc503c3a44c1919f8ce..16ddf052675945fbef38272c3c3f85841cb9aae7 100644 (file)
--- a/src/cli.c
+++ b/src/cli.c
@@ -2278,8 +2278,8 @@ int pcli_find_and_exec_kw(struct stream *s, char **args, int argl, char **errmsg
  */
 int pcli_parse_request(struct stream *s, struct channel *req, char **errmsg, int *next_pid)
 {
-       char *str = (char *)ci_head(req);
-       char *end = (char *)ci_stop(req);
+       char *str;
+       char *end;
        char *args[MAX_CLI_ARGS + 1]; /* +1 for storing a NULL */
        int argl; /* number of args */
        char *p;
@@ -2290,6 +2290,15 @@ int pcli_parse_request(struct stream *s, struct channel *req, char **errmsg, int
        int ret;
        int i = 0;
 
+       /* we cannot deal with a wrapping buffer, so let's take care of this
+        * first.
+        */
+       if (b_head(&req->buf) + b_data(&req->buf) > b_wrap(&req->buf))
+               b_slow_realign(&req->buf, trash.area, co_data(req));
+
+       str = (char *)ci_head(req);
+       end = (char *)ci_stop(req);
+
        p = str;
 
        if (!(s->pcli_flags & PCLI_F_PAYLOAD)) {