php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #76058 After "POST data can't be buffered", using php://input makes huge tmp files
Submitted: 2018-03-06 01:55 UTC Modified: -
Votes:13
Avg. Score:4.4 ± 1.2
Reproduced:12 of 12 (100.0%)
Same Version:6 (50.0%)
Same OS:10 (83.3%)
From: mwrusnak at gmail dot com Assigned:
Status: Closed Package: Streams related
PHP Version: 7.1.15 OS: linux
Private report: No CVE-ID: None
 [2018-03-06 01:55 UTC] mwrusnak at gmail dot com
Description:
------------
In the patch for bug #69487 (https://bugs.php.net/bug.php?id=69487), this PHP warning was added "POST data can't be buffered; all data discarded", which works fine, but if "php://input" is read after that occurs, it can sometimes make large temp files, often multiple GB in size. If there is a timeout and PHP is killed while writing these files, they remain in the temp directory.

I have only seen it happen when users have mod_lsapi from CloudLinux, but I can reproduce it with the regular lsapi binary by sending a similar bad request. Using "strace", I copied what the real LiteSpeed web server sent to lsphp during a normal POST request, then I sent the same request to lsphp from a script, but without the POST body, and then killed the "sending" end (normally LiteSpeed or mod_lsapi).

The initial cases I saw with this issue included logs from "strace", showing:
- A broken pipe when PHP tries to read the POST body from the web server
- The error message above
- A /tmp/phpxxxxxxx file being opened
- Huge volumes of data being written to that temp file's fd, when php://input is read.

As far as I can tell, the temp files are caused by php_stream_input_read() calling php_stream_write(), while the data provided by sapi_read_post_block() (via the litespeed SAPI) is bad, due to the broken pipe. The temp file content seems to be contents of memory, not part of a HTTP POST request.

These are two discussions I know of, with some of the same users:
https://forums.cpanel.net/threads/big-phpxxxxxx-files-in-home-user-cagefs-tmp.609659/
https://wordpress.org/support/topic/big-phpxxxxxx-files-in-home-user-cagefs-tmp/

Though the issue is hard to reproduce on demand (and it doesn't seem that a .phpt could be written for it), when the message "POST data can't be buffered; all data discarded" occurs, and then the script tries to read "php://input", could PHP treat the input stream as empty, without trying to read it again? Or is it better to prevent it in lsapi?

Test script:
---------------
Two scripts are here, one to run lsapi, and one to simulate a request from the web server:
https://github.com/mwrusnak/lsapi-issue-2018-03
(`strace` output from monitoring the lsapi "index.html" script is also included)

Expected result:
----------------
Reading "php://input" in a script should immediately return 0 bytes if the message "POST data can't be buffered; all data discarded" has already occurred when PHP originally tried to read the request body.

Actual result:
--------------
PHP writes a large temporary file with a name like /tmp/phpQQnomb, sometimes multiple GB in size. Usually PHP is killed before the script finishes running.

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2019-07-04 16:03 UTC] gwang@php.net
Automatic comment on behalf of gwang
Revision: http://git.php.net/?p=php-src.git;a=commit;h=32af676bd9f13815d40138a2299e862a3c6985cf
Log: Updated to LiteSpeed SAPI V7.4.3 Increased response header count limit from 100 to 1000. Added crash handler to cleanly shutdown PHP request. Added CloudLinux mod_lsapi mode Fixed bug #76058
 [2019-07-04 16:03 UTC] gwang@php.net
-Status: Open +Status: Closed
 [2019-07-04 16:04 UTC] gwang@php.net
Automatic comment on behalf of gwang
Revision: http://git.php.net/?p=php-src.git;a=commit;h=32af676bd9f13815d40138a2299e862a3c6985cf
Log: Updated to LiteSpeed SAPI V7.4.3 Increased response header count limit from 100 to 1000. Added crash handler to cleanly shutdown PHP request. Added CloudLinux mod_lsapi mode Fixed bug #76058
 [2019-07-04 16:14 UTC] gwang@php.net
Automatic comment on behalf of gwang
Revision: http://git.php.net/?p=php-src.git;a=commit;h=32af676bd9f13815d40138a2299e862a3c6985cf
Log: Updated to LiteSpeed SAPI V7.4.3 Increased response header count limit from 100 to 1000. Added crash handler to cleanly shutdown PHP request. Added CloudLinux mod_lsapi mode Fixed bug #76058
 [2019-07-04 16:15 UTC] gwang@php.net
Automatic comment on behalf of gwang
Revision: http://git.php.net/?p=php-src.git;a=commit;h=32af676bd9f13815d40138a2299e862a3c6985cf
Log: Updated to LiteSpeed SAPI V7.4.3 Increased response header count limit from 100 to 1000. Added crash handler to cleanly shutdown PHP request. Added CloudLinux mod_lsapi mode Fixed bug #76058
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Tue Aug 20 14:01:47 2019 UTC