Bug 1213411

Summary: php: use-after-free vulnerability in php_curl related to CURLOPT_FILE/_INFILE/_WRITEHEADER
Product: [Other] Security Response Reporter: Vasyl Kaigorodov <vkaigoro>
Component: vulnerabilityAssignee: Red Hat Product Security <security-response-team>
Status: CLOSED WONTFIX QA Contact:
Severity: low Docs Contact:
Priority: low    
Version: unspecifiedCC: bleanhar, ccoleman, dmcphers, fedora, jdetiber, jialiu, jkeck, jokerman, jorton, kseifried, lmeyer, mmaslano, mmccomas, rcollet, webstack-team
Target Milestone: ---Keywords: Security
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: php 5.4.40, php 5.5.24, php 5.6.8 Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2015-05-18 21:07:33 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On: 1213456    
Bug Blocks: 1213462    

Description Vasyl Kaigorodov 2015-04-20 13:52:17 UTC
PHP versions 5.4.40, 5.5.24, and 5.6.8 provide a fix for use-after-free vulnerability in php_curl related to CURLOPT_FILE/_INFILE/_WRITEHEADER, which under certain circumstances might lead to arbitrary code execution.
Some details from the upstream bug:
"""
When using CURLOPT_WRITEHEADER, CURLOPT_INFILE or CURLOPT_FILE, in _php_curl_setopt, the provided stream is cast to a stdio FILE*:

if (FAILURE == php_stream_cast((php_stream *) what, PHP_STREAM_AS_STDIO, (void *) &fp, REPORT_ERRORS)) {
  return FAILURE;
}

This FILE* is then stored in the php_curl structure "ch", at the following locations, depending on which CURLOPT_ was used:
- ch->handlers->write->fp = fp;
- ch->handlers->write_header->fp = fp;
- ch->handlers->read->fp = fp;

Upon curl_exec(), _php_curl_verify_handlers() is called, which verifies if the user-set stream(s) are still open, and resets ->fp to 0 if they are not.

However, there are a number of curl callbacks we can use to close the stream after _php_curl_verify_handlers() has been called, resulting in the FILE* being free()'d. By allocating memory that ends up a the same address where the FILE structure was, its possible to achieve arbitrary code execution.

The following functions use *->fp without checking if the corresponding streams are still open (and thus if *->fp still points to a valid FILE structure or not):
- static size_t curl_write(char *data, size_t size, size_t nmemb, void *ctx)
- static size_t curl_read(char *data, size_t size, size_t nmemb, void *ctx)
- static size_t curl_write_header(char *data, size_t size, size_t nmemb, void *ctx)
- curl_exec (after curl processing is finished, there are 2 fflush() calls)

On Linux, with PHP linked against GLIBC, arbitrary code execution is trivial, since FILE structures conveniently have a "vtable" full of function pointers which we now control.
"""

Upstream fix: http://git.php.net/?p=php-src.git;a=commit;h=0ea75af9be8a40836951fc89f723dd5390b8b46f
Upstream bug: https://bugs.php.net/bug.php?id=69316

Comment 1 Vasyl Kaigorodov 2015-04-20 15:24:50 UTC
Created php tracking bugs for this issue:

Affects: fedora-all [bug 1213456]

Comment 2 Fedora Update System 2015-04-22 22:51:51 UTC
php-5.6.8-1.fc22 has been pushed to the Fedora 22 stable repository.  If problems still persist, please make note of it in this bug report.

Comment 3 Fedora Update System 2015-04-23 16:10:55 UTC
php-5.6.8-1.fc21 has been pushed to the Fedora 21 stable repository.  If problems still persist, please make note of it in this bug report.

Comment 4 Fedora Update System 2015-04-27 08:39:17 UTC
php-5.5.24-1.fc20 has been pushed to the Fedora 20 stable repository.  If problems still persist, please make note of it in this bug report.

Comment 5 Tomas Hoger 2015-05-18 21:07:33 UTC
This problem can only be triggered by a malicious script author.  As PHP does not provide any reliable sandbox to run untrusted code (e.g. safe mode feature was available in PHP versions before 5.4.0, but was removed as "architecturally incorrect" and incapable of reliably sandboxing executed code), any executed PHP code must be trusted with the privileges of the PHP interpreter.  Therefore, this issue is not planned to be fixed in already released Red Hat product versions.  Future product versions based on fixed upstream PHP versions may include a fix for this issue.