php / php-src

The PHP Interpreter
https://www.php.net
Other
38.16k stars 7.75k forks source link

ping stops responding when size of env chars exceeds specific amount #16042

Open nonsenz opened 1 month ago

nonsenz commented 1 month ago

Description

i can reproduce this with the official docker images (tried php:8.3.10-fpm-alpine3.19 and php:8.4.0beta5-fpm-alpine3.20) doing this:

docker run --rm --name phptest php:8.3.10-fpm-alpine3.19 sh -c "apk add --no-cache fcgi && \
  sed -i '/ping\.path/d' /usr/local/etc/php-fpm.d/www.conf && \
  sed -i '/ping\.response/d' /usr/local/etc/php-fpm.d/www.conf && \
  echo 'ping.path = /ping' >> /usr/local/etc/php-fpm.d/www.conf && \
  echo 'ping.response = pong' >> /usr/local/etc/php-fpm.d/www.conf && \
  php-fpm"

when i enter the container and trigger the ping it looks like this:

# SCRIPT_NAME=/ping SCRIPT_FILENAME=/ping REQUEST_METHOD=GET cgi-fcgi -bind -connect 127.0.0.1:9000
X-Powered-By: PHP/8.3.10
Content-type: text/plain;charset=UTF-8
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Cache-Control: no-cache, no-store, must-revalidate, max-age=0

pong

when i now create a bunch of envs, ping stops working:

i=1; while [ $i -le 494 ]; do export TEST_ENV_$i=f; i=$((i + 1)); done && SCRIPT_NAME=/ping SCRIPT_FILENAME=/ping REQUEST_METHOD=GET cgi-fcgi -bind -connect 127.0.0.1:9000

maybe this is not a bug, but i could not find any information regarding a size/limit that can be configured. it looks that my php application still works, even if ping does not respond anymore.

thx for any information or hints 🙏

PHP Version

tested with php:8.3.10-fpm-alpine3.19 and php:8.4.0beta5-fpm-alpine3.20

Operating System

docker alpine 3.19 and 3.20

nielsdos commented 1 week ago

I think this is a bug in the fastcgi handling of FCGI_PARAMS. The request is ignored by fcgi_get_params because we receive a FCGI_PARAMS packet where name_len + val_len > (unsigned int) (end - p) is true:

https://github.com/php/php-src/blob/551a9ef5e66bbcd421a7a08ff869bb210e9299d8/main/fastcgi.c#L1026-L1029

It turns out that the value is split across two FCGI_PARAMS packets. This seems legal according to section B example 2 of https://www.mit.edu/~yandros/doc/specs/fcgi-spec.html#S5.2