]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: mux-fcgi: check the room left before appending the index
authorOlivier Houchard <ohouchard@haproxy.com>
Thu, 6 Aug 2026 07:21:38 +0000 (09:21 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 7 Aug 2026 08:29:19 +0000 (10:29 +0200)
In fcgi_set_default_param(), when the decoded path ends with a '/' and the
fcgi-app declares an "index", params->scriptname is set to span the path
plus the index before both are appended to the trash chunk, and the return
value of these appends is ignored. If the chunk is full, nothing is written
but scriptname still points past its tail, so SCRIPT_NAME and
SCRIPT_FILENAME are encoded from memory located past the end of the chunk
and sent to the FastCGI application. The copy of the path a few lines above
was not checked either. Since the URI is copied into the chunk first and
the path copied again, a path larger than about a third of a buffer is
enough to reach this.

Let's check both appends and only publish the script name once its content
is really there.

Reported-by: Claude (ANT-2026-WPM4GZPQ)
src/mux_fcgi.c

index 3c8f0d2e1deeb688a2716164b71fd7ce8afd23bb..6ec20dab13bed309886236ba9a7fe1b127a35729 100644 (file)
@@ -1328,7 +1328,8 @@ static int fcgi_set_default_param(struct fcgi_conn *fconn, struct fcgi_strm *fst
                /* Decode the path. it must first be copied to keep the URI
                 * untouched.
                 */
-               chunk_istcat(params->p, path);
+               if (!chunk_istcat(params->p, path))
+                       goto error;
                path.ptr = b_tail(params->p) - path.len;
                len = url_decode(ist0(path), 0);
                if (len < 0)
@@ -1380,10 +1381,15 @@ static int fcgi_set_default_param(struct fcgi_conn *fconn, struct fcgi_strm *fst
                 */
                if (istlen(fconn->app->index) && params->scriptname.ptr[len-1] == '/') {
                        struct ist sn = params->scriptname;
+                       char *ptr = b_tail(params->p);
 
-                       params->scriptname = ist2(b_tail(params->p), len+fconn->app->index.len);
-                       chunk_istcat(params->p, sn);
-                       chunk_istcat(params->p, fconn->app->index);
+                       /* both appends must succeed, otherwise scriptname would
+                        * advertise more bytes than what was really stored.
+                        */
+                       if (!chunk_istcat(params->p, sn) ||
+                           !chunk_istcat(params->p, fconn->app->index))
+                               goto error;
+                       params->scriptname = ist2(ptr, len + fconn->app->index.len);
                }
        }