From e90c6b5681f33f2cfefa3004fcce7ebe7bc6a8fa Mon Sep 17 00:00:00 2001 From: Ilia Alshanetsky Date: Fri, 21 Aug 2026 13:11:59 -0400 Subject: [PATCH] Fix path_info pointer underflow in CGI fix_pathinfo handling When the PATH_INFO supplied by the webserver is shorter than the suffix stripped from SCRIPT_FILENAME, computing env_path_info + pilen - slen underflows and the subsequent path_info[0] = 0 writes out of bounds before the start of the string. The FPM side of this same loop was hardened by commit ab061f95ca9 (CVE-2019-11043) but sapi/cgi was never given the equivalent guard. Mirror it: only derive path_info when pilen exceeds slen, and skip the ORIG_*/SCRIPT_NAME juggling when there is no extracted path. --- sapi/cgi/cgi_main.c | 4 +-- sapi/cgi/tests/fix_pathinfo_underflow.phpt | 37 ++++++++++++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 sapi/cgi/tests/fix_pathinfo_underflow.phpt diff --git a/sapi/cgi/cgi_main.c b/sapi/cgi/cgi_main.c index 0e7b3009c602..7ca8d5e2552a 100644 --- a/sapi/cgi/cgi_main.c +++ b/sapi/cgi/cgi_main.c @@ -1285,9 +1285,9 @@ static void init_request_info(fcgi_request *request) */ size_t slen = len - strlen(pt); size_t pilen = env_path_info ? strlen(env_path_info) : 0; - char *path_info = env_path_info ? env_path_info + pilen - slen : NULL; + char *path_info = (env_path_info && pilen > slen) ? env_path_info + pilen - slen : NULL; - if (orig_path_info != path_info) { + if (path_info != NULL && orig_path_info != path_info) { if (orig_path_info) { char old; diff --git a/sapi/cgi/tests/fix_pathinfo_underflow.phpt b/sapi/cgi/tests/fix_pathinfo_underflow.phpt new file mode 100644 index 000000000000..e737fee1dc7c --- /dev/null +++ b/sapi/cgi/tests/fix_pathinfo_underflow.phpt @@ -0,0 +1,37 @@ +--TEST-- +cgi fix_pathinfo with PATH_INFO shorter than the stripped suffix +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +X-Powered-By: PHP/%s +Content-type: text/html%r; charset=.*|%r + +PI=[/] +Done