php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #79102 php-cgi.exe exits when processing SabreDAV requests
Submitted: 2020-01-11 18:33 UTC Modified: 2022-01-20 17:11 UTC
Votes:3
Avg. Score:3.7 ± 0.9
Reproduced:2 of 2 (100.0%)
Same Version:1 (50.0%)
Same OS:0 (0.0%)
From: mbiebl at messageconcept dot com Assigned:
Status: Open Package: IIS related
PHP Version: 7.3.13 OS: Windows Server 2016
Private report: No CVE-ID: None
 [2020-01-11 18:33 UTC] mbiebl at messageconcept dot com
Description:
------------
Hello,

we are using SabreDAV http://sabre.io/ under Windows/IIS and run into an interesting problem.
Whenever a request with request data is sent to SabreDAV, the php-cgi.exe process exits.
PHP is version 7.3.13, we use IIS with fastcgi.
https://mynebula.net/index.php/s/b3fAYyYei6G5tjA demonstrates the problem.

Unfortunately, it's not trivial to reduce the issue to a short reproducer script.
If you want to reproduce the issue, the following steps are necessary

1/ Download the zip file from https://mynebula.net/index.php/s/3JsoEfbXcpgCiet
2/ Setup an IIS website pointing at the directory where you unpackage the zipfile, I used port 9090 as binding
3/ Make sure the site is configured as in the web.config, you will need to adjust the path to the php binary
4/ run curl as in test.sh

What we figured out so far is, that the problem only happens, if curl is sending request data. We can work around the problem by adding a line
 file_get_contents('php://input');
in server.php before the 
 $server->exec(); 
line

I tried to run xdebug with a function trace, trying to figure out what's going on, but unfortunately I'm kinda stuck at this point.
It's not clear to me, we php-cgi.exe simply exits after processing the request.

Test script:
---------------
composer.json
==============
{
	"require" : {
		"sabre/dav" : "4.0.*" 
	}
}

server.php
==========
<?php

/*

Addressbook/CardDAV server example

This server features CardDAV support

*/

#xdebug_start_trace();

function exception_error_handler($errno, $errstr, $errfile, $errline ) {
    throw new \ErrorException($errstr, 0, $errno, $errfile, $errline);
}
set_error_handler('exception_error_handler');

// settings
date_default_timezone_set('Europe/Berlin');

// Make sure this setting is turned on and reflect the root url for your WebDAV server.
// This can be for example the root / or a complete path to your server script
$baseUri = '/';

/* Database */
$pdo = new PDO('sqlite:data/db.sqlite');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

// Autoloader
require_once 'vendor/autoload.php';

// Backends
$authBackend = new Sabre\DAV\Auth\Backend\PDO($pdo);
$principalBackend = new Sabre\DAVACL\PrincipalBackend\PDO($pdo);
$carddavBackend = new Sabre\CardDAV\Backend\PDO($pdo);

// Setting up the directory tree //
$nodes = [
    new Sabre\DAVACL\PrincipalCollection($principalBackend),
    new Sabre\CardDAV\AddressBookRoot($principalBackend, $carddavBackend),
];

// The object tree needs in turn to be passed to the server class
$server = new Sabre\DAV\Server($nodes);
$server->setBaseUri($baseUri);

// Plugins
$server->addPlugin(new Sabre\DAV\Auth\Plugin($authBackend));
$server->addPlugin(new Sabre\DAV\Browser\Plugin());
$server->addPlugin(new Sabre\CardDAV\Plugin());
$server->addPlugin(new Sabre\DAV\Sync\Plugin());
// Hide nodes that the user does not have access to
$aclPlugin = new \Sabre\DAVACL\Plugin();
$aclPlugin->hideNodesFromListings = true;
$aclPlugin->allowUnauthenticatedAccess = false;
$server->addPlugin($aclPlugin);

// And off we go!
$server->start();


web.config
==========
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <rewrite>
            <rules>
                <rule name="Rewrite to server.php">
                    <match url=".*" />
                    <action type="Rewrite" url="server.php" />
                </rule>
            </rules>
        </rewrite>
        <security>
            <requestFiltering>
                <verbs>
                    <add verb="PROPFIND" allowed="true" />
                </verbs>
            </requestFiltering>
        </security>
        <handlers>
            <remove name="WebDAV" />
            <add name="PHP7_via_FastCGI" path="*.php" verb="OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, COPY, MOVE, MKCOL, PROPFIND, PROPPATCH, LOCK, UNLOCK, REPORT, ACL" modules="FastCgiModule" scriptProcessor="C:\Program Files (x86)\PHP\v7.3\php-cgi.exe" resourceType="Either" requireAccess="Script" />
        </handlers>
        <defaultDocument enabled="false">
            <files>
                <remove value="index.php" />
                <remove value="default.aspx" />
                <add value="server.php" />
            </files>
        </defaultDocument>
        <modules>
            <remove name="WebDAVModule" />
        </modules>
    </system.webServer>
</configuration>

test.sh
=======
user=admin
pass=admin

for i in `seq 1 5`; do
curl -H "Accept: text/xml" -H "Content-Type: text/xml; charset=utf-8" -X PROPFIND http://localhost:9090/ \
	--data '<?xml version="1.0" encoding="utf-8"?><D:propfind xmlns:D="DAV:"><D:prop><addressbook-home-set xmlns="urn:ietf:params:xml:ns:carddav" /></D:prop></D:propfind>'
done



Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2020-01-11 18:43 UTC] mbiebl at messageconcept dot com
I tried to reproduce the issue under Debian, using Apache and PHP via FPM, but was unsuccessful.
So it seems specific PHP/IIS
 [2020-01-11 19:50 UTC] requinix@php.net
-Status: Open +Status: Feedback
 [2020-01-11 19:50 UTC] requinix@php.net
Thank you for this bug report. To properly diagnose the problem, we
need a backtrace to see what is happening behind the scenes. To
find out how to generate a backtrace, please read
http://bugs.php.net/bugs-generating-backtrace.php for *NIX and
http://bugs.php.net/bugs-generating-backtrace-win32.php for Win32

Once you have generated a backtrace, please submit it to this bug
report and change the status back to "Open". Thank you for helping
us make PHP better.


 [2020-01-11 20:53 UTC] mbiebl at messageconcept dot com
-Status: Feedback +Status: Open
 [2020-01-11 20:53 UTC] mbiebl at messageconcept dot com
Thanks for the switft reply.
Afaics, php-cgi.exe does not actually crash. Otherwise I would expect a trace of that in the windows event log. But nothing is logged there. Neither is there anything in the PHP error log.

Is it possible to actually get a backtrace if a process doesn't crash but simply exits? If so, how do I do it then?

What I do have is a function trace from xdebug. 
See https://mynebula.net/index.php/s/F6QAZwYdLK5MaNx

Btw, is there a way to attach files to this bug report?
 [2020-01-11 20:59 UTC] mbiebl at messageconcept dot com
cgi-fcgi
========
Directive		Local Value	Master Value
cgi.check_shebang_line	1	1
cgi.discard_path	0	0
cgi.fix_pathinfo	1	1
cgi.force_redirect	0	0
cgi.nph			0	0
cgi.redirect_status_env	no value	no value
cgi.rfc2616_headers	0	0
fastcgi.impersonate	1	1
fastcgi.logging		1	1
 [2020-07-20 14:01 UTC] cmb@php.net
-Status: Open +Status: Feedback -Assigned To: +Assigned To: cmb
 [2020-07-20 14:01 UTC] cmb@php.net
Are you still experiencing this issue with PHP 7.3.20?  If so,
could you please make the files available again?
 [2020-07-29 08:23 UTC] mbiebl at messageconcept dot com
-Status: Feedback +Status: Assigned
 [2020-07-29 08:23 UTC] mbiebl at messageconcept dot com
Hi,
I tried with 7.3.20 (x86) and 7.4.8 (x64) and could still reproduce the issue.
I made the zip file available at https://mynebula.net/index.php/s/pf8XMciDxEHeqXD
 [2020-07-31 16:57 UTC] cmb@php.net
-Status: Assigned +Status: Feedback
 [2020-07-31 16:57 UTC] cmb@php.net
I cannot reproduce the reported issue, but that may be because
unauthenticated access doesn't work for me, regardless of the
setting of ::allowUnauthenticatedAccess; I get an
Sabre\DAV\Exception\NotAuthenticated either way.

What am I missing?

Link to respective upstream report:
<https://github.com/sabre-io/dav/issues/1224>.
 [2020-08-09 04:22 UTC] php-bugs at lists dot php dot net
No feedback was provided. The bug is being suspended because
we assume that you are no longer experiencing the problem.
If this is not the case and you are able to provide the
information that was requested earlier, please do so and
change the status of the bug back to "Re-Opened". Thank you.
 [2022-01-20 17:04 UTC] mbiebl at messageconcept dot com
I can still reproduce the issue with 7.4.27 and 8.0.15

The download link has expired, but I created a new one where I've updated the test.sh script. It will run a loop and generate an unauthenticated access (causing the php-cgi.exe process to die) and a second, authenticated access, where the process doesn't die.

The new download link with the updated script can be found at
https://mynebula.net/s/scY6aAbHr5gq8i7
 [2022-01-20 17:11 UTC] cmb@php.net
-Status: No Feedback +Status: Open -Assigned To: cmb +Assigned To:
 [2022-12-15 12:22 UTC] Armand857Smith at gmail dot com
I finally figured it out. Maybe it was simple enough that I couldn't find the solution.

Adding:

SET PHP_FCGI_MAX_REQUESTS=0 
to the command file that launches the php-cgi.exe fixed it. I guess it defaults (when not set) to 500 hits before FCGI is killed.

(https://www.dunkinrunsonyou.run/)github.com
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Dec 10 11:01:28 2024 UTC