|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2010-02-09 20:53 UTC] php at linepoint dot com
Description: ------------ PHP v5.3+ now forces fastcgi support to be compiled into the executable, and upon execution of php-cgi, auto selects which mode (fastcgi/cgi) is to be used. In some circumstances, it can guess incorrectly and use fastcgi mode when cgi mode should be used. PHP's method of checking in sapi/cgi/fastcgi.c (line ~230) uses the errno returned (ENOTCONN) as an assumption that a local/unix socket connection must be a fastcgi call. A alternative or secondary check should be implemented to verify that it's truly a fastcgi execution. This problem was initially found when working with the Zeus Webserver (http://www.zeus.com), but can be reproduced with other systems that work the same way. Reproduce code: --------------- When php-cgi is called from a webserver, it checks stdin (fd 0) with a getpeername call to see if it's reading via a socket or not. In some circumstances/webservers, php-cgi can be called using local sockets instead of file, but not be executed with fastcgi hooks. Code in question: --- sapi/cgi/fastcgi.c.orig 2010-02-09 12:25:49.000000000 -0500 } #else errno = 0; if (getpeername(0, (struct sockaddr *)&sa, &len) != 0 && errno == ENOTCONN) { fcgi_setup_signals(); return is_fastcgi = 1; } else { --- Expected result: ---------------- Expected result is that fastcgi mode is used for fastcgi calls, and cgi mode is used for cgi calls. A "proof of concept" patch which fixes the issue (this is not a final patch due to the fact the environmental variable checked is optional, not mandatory) --- sapi/cgi/fastcgi.c.orig 2010-02-09 12:25:49.000000000 -0500 +++ sapi/cgi/fastcgi.c 2010-02-09 12:26:50.000000000 -0500 @@ -228,7 +228,7 @@ } #else errno = 0; - if (getpeername(0, (struct sockaddr *)&sa, &len) != 0 && errno == ENOTCONN) { + if (getpeername(0, (struct sockaddr *)&sa, &len) != 0 && errno == ENOTCONN && getenv ("PHP_FCGI_CHILDREN") ) { fcgi_setup_signals(); return is_fastcgi = 1; } else { Actual result: -------------- The current code auto selects fastcgi mode, when cgi mode is the desired result. PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Mon Nov 03 02:00:02 2025 UTC |
The getpeername() check came from the reference libfcgi implementation. The additional check for getenv("PHP_FCGI_CHILDREN") is not correct because PHP_FCGI_CHILDREN don't have to be set. Really I can't find out a different check which will portable across different FastCGI managers. Especially for Zeus (and any other web server which supports FastCGI) I would suggest to use FastCGI instead of CGI.