Hide Forgot
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.
Acknowledgments: Name: Hans Jerry Illikainen
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.
Upstream bug: https://bugs.php.net/bug.php?id=72321 Upstream commit: http://git.php.net/?p=php-src.git;a=commitdiff;h=d144590d38fa321b46b8e199c754006318985c84 Fixed upstream in 5.6.23: http://php.net/ChangeLog-5.php#5.6.23
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