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
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: mwrusnak at gmail dot com
New email:
PHP Version: OS:

 

 [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

Pull Requests

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-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 21 13:01:31 2024 UTC