ID: 50979 Updated by: johan...@php.net Reported By: php at linepoint dot com -Status: Open +Status: Assigned Bug Type: CGI related Operating System: Freebsd PHP Version: 5.3.1 -Assigned To: +Assigned To: dmitry
Previous Comments: ------------------------------------------------------------------------ [2010-02-09 20:53:47] 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. ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/?id=50979&edit=1