Bug 1347772 (CVE-2016-4473) - CVE-2016-4473 php: Invalid free() instead of efree() in phar_extract_file()
Summary: CVE-2016-4473 php: Invalid free() instead of efree() in phar_extract_file()
Keywords:
Status: CLOSED ERRATA
Alias: CVE-2016-4473
Product: Security Response
Classification: Other
Component: vulnerability
Version: unspecified
Hardware: All
OS: Linux
medium
medium
Target Milestone: ---
Assignee: Red Hat Product Security
QA Contact:
URL:
Whiteboard:
Depends On:
Blocks: 1347776
TreeView+ depends on / blocked
 
Reported: 2016-06-17 15:21 UTC by Adam Mariš
Modified: 2021-02-17 03:42 UTC (History)
13 users (show)

Fixed In Version: php 5.6.23
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
Environment:
Last Closed: 2016-06-23 14:22:04 UTC
Embargoed:


Attachments (Terms of Use)


Links
System ID Private Priority Status Summary Last Updated
Red Hat Product Errata RHSA-2016:2750 0 normal SHIPPED_LIVE Moderate: rh-php56 security, bug fix, and enhancement update 2016-11-15 16:40:02 UTC

Description Adam Mariš 2016-06-17 15:21:10 UTC
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 15:21:19 UTC
Acknowledgments:

Name: Hans Jerry Illikainen

Comment 3 Tomas Hoger 2016-06-23 14:22:04 UTC
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 11:41:06 UTC
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.