Bugzilla will be upgraded to version 5.0. The upgrade date is tentatively scheduled for 2 December 2018, pending final testing and feedback.
Bug 1347772 - (CVE-2016-4473) CVE-2016-4473 php: Invalid free() instead of efree() in phar_extract_file()
CVE-2016-4473 php: Invalid free() instead of efree() in phar_extract_file()
Status: CLOSED ERRATA
Product: Security Response
Classification: Other
Component: vulnerability (Show other bugs)
unspecified
All Linux
medium Severity medium
: ---
: ---
Assigned To: Red Hat Product Security
impact=moderate,public=20160621,repor...
: Security
Depends On:
Blocks: 1347776
  Show dependency treegraph
 
Reported: 2016-06-17 11:21 EDT by Adam Mariš
Modified: 2016-11-15 09:43 EST (History)
12 users (show)

See Also:
Fixed In Version: php 5.6.23
Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2016-06-23 10:22:04 EDT
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)


External Trackers
Tracker ID Priority Status Summary Last Updated
Red Hat Product Errata RHSA-2016:2750 normal SHIPPED_LIVE Moderate: rh-php56 security, bug fix, and enhancement update 2016-11-15 11:40:02 EST

  None (edit)
Description Adam Mariš 2016-06-17 11:21:10 EDT
It was reported that invalid free may occur under certain conditions when processing phar-compatible archives in php 7.0.7 and 5.6.22.

Vulnerable code (php-7.0.7/ext/phar/phar_object.c):

| 4063 static int phar_extract_file(zend_bool overwrite, phar_entry_info *entry, char *dest, int dest_len, char **error) /* {{{ */
| 4064 {
| ....
| 4071 cwd_state new_state;
| ....
| 4084 new_state.cwd = (char*)emalloc(2); // (1)
| 4085 new_state.cwd[0] = DEFAULT_SLASH;
| 4086 new_state.cwd[1] = '\0';
| 4087 new_state.cwd_length = 1;
| 4088 if (virtual_file_ex(&new_state, entry->filename, NULL, CWD_EXPAND) != 0 ||
| 4089 new_state.cwd_length <= 1) {
| ....
| 4099 }
| ....
| 4163
| 4164 if (FAILURE == php_stream_stat_path(fullpath, &ssb)) {
| 4165 if (entry->is_dir) {
| 4166 if (!php_stream_mkdir(fullpath, entry->flags & PHAR_ENT_PERM_MASK, PHP_STREAM_MKDIR_RECURSIVE, NULL)) { // (2)
| ....
| 4169 free(new_state.cwd);
| ....
| 4171 }
| 4172 } else {
| 4173 if (!php_stream_mkdir(fullpath, 0777, PHP_STREAM_MKDIR_RECURSIVE, NULL)) { // (3)
| ....
| 4176 free(new_state.cwd);
| ....
| 4178 }
| 4179 }
| 4180 }
| ....
| 4246 }

`new_state.cwd' is initially allocated through the internal zend allocator in (1) and is later reallocated as the file path is resolved.

In `virtual_file_ex' (php-7.0.7/Zend/zend_virtual_cwd.c):

| 1178 CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func verify_path, int use_realpath) /* {{{ */
| 1179 {
| ....
| 1336 if (verify_path) {
| ....
| 1342 tmp = erealloc(state->cwd, state->cwd_length+1);
| ....
| 1349 state->cwd = (char *) tmp;
| 1350
| 1351 memcpy(state->cwd, resolved_path, state->cwd_length+1);
| ....
| 1360 } else {
| ....
| 1362 tmp = erealloc(state->cwd, state->cwd_length+1);
| ....
| 1369 state->cwd = (char *) tmp;
| 1370
| 1371 memcpy(state->cwd, resolved_path, state->cwd_length+1);
| ....
| 1373 }
| ....
| 1379 }

If `php_stream_mkdir' fails in (2) or (3), `cwd' is freed by the underlying libc allocator. If `cwd' is user-controlled, this could potentially result in code execution.
Comment 1 Adam Mariš 2016-06-17 11:21:19 EDT
Acknowledgments:

Name: Hans Jerry Illikainen
Comment 3 Tomas Hoger 2016-06-23 10:22:04 EDT
Affected code was introduced as part of the fix for CVE-2015-6833 (bug 1283702), which was applied upstream in versions 5.4.44, 5.5.28, and 5.6.12.  However, this problem only affects 5.6 versions, which required this additional fix:

https://git.php.net/?p=php-src.git;a=commitdiff;h=eb7ba73079b73ca4ef91307ae1ef30b43468717b

This commit failed to change all free(new_state.cwd) to efree(new_state.cwd).

This issue is triggered when extracting Zip-based Phar archive to a directory that already contains a file of the same name as a directory to be extracted.

Phar files are distribution format for PHP applications (similar to Java Jar format) and their content is typically executed on the server.  Malicious Phar archive can therefore execute code on the system without exploiting any parsing issues.

If Phar extension is not used, it can be disabled by commenting out the following line:

  extension=phar.so

in phar.ini to prevent loading of the extension.
Comment 5 errata-xmlrpc 2016-11-15 06:41:06 EST
This issue has been addressed in the following products:

  Red Hat Software Collections for Red Hat Enterprise Linux 6
  Red Hat Software Collections for Red Hat Enterprise Linux 6.7 EUS
  Red Hat Software Collections for Red Hat Enterprise Linux 7
  Red Hat Software Collections for Red Hat Enterprise Linux 7.2 EUS
  Red Hat Software Collections for Red Hat Enterprise Linux 7.3 EUS

Via RHSA-2016:2750 https://rhn.redhat.com/errata/RHSA-2016-2750.html

Note You need to log in before you can comment on or make changes to this bug.