|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
[2016-06-03 06:52 UTC] hji at dyntopia dot com
[2016-06-04 23:09 UTC] stas@php.net
-PHP Version: 7.0.7
+PHP Version: 5.6.22
[2016-06-13 04:36 UTC] stas@php.net
-Assigned To:
+Assigned To: stas
[2016-06-13 04:36 UTC] stas@php.net
[2016-06-21 07:03 UTC] stas@php.net
[2016-06-21 07:03 UTC] stas@php.net
-Status: Assigned
+Status: Closed
[2016-06-21 07:26 UTC] stas@php.net
[2016-06-21 07:27 UTC] stas@php.net
[2016-06-22 05:58 UTC] krakjoe@php.net
[2016-09-21 12:17 UTC] kaplan@php.net
-CVE-ID:
+CVE-ID: 2016-4473
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sat Oct 25 22:00:01 2025 UTC |
Description: ------------ An invalid free (assigned CVE-2016-4473) may occur under certain conditions when processing phar-compatible archives in php 5.6.22, 7.0.7 and git head: 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); // (3) | .... | 4171 } | 4172 } else { | 4173 if (!php_stream_mkdir(fullpath, 0777, PHP_STREAM_MKDIR_RECURSIVE, NULL)) { // (4) | .... | 4176 free(new_state.cwd); // (5) | .... | 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 } `---- However, should `php_stream_mkdir' fail in (2) or (4), `cwd' is freed by the underlying libc allocator in (3) or (5). Test script: --------------- mkzip.py: https://gist.github.com/dyntopia/9e54d61674ca89cd1381fbb017791e39 phar.php: https://gist.github.com/dyntopia/b7133c623bafe3ff7b7f57e38d7b2f90 Actual result: -------------- On FreeBSD (ie. jemalloc) with mkdir() failing due to a directory already existing as a regular file: $ python mkzip.py $ gdb711 --args php phar.php out/ 1.zip 2.zip (gdb) r Starting program: /usr/home/php/php/bin/php phar.php out/ 1.zip 2.zip Warning: PharData::extractTo(): Not a directory in /usr/home/php/phar.php on line 14 Program received signal SIGBUS, Bus error. 0x00000008025bde2c in __jemalloc_arena_dalloc_bin_locked (arena=<optimized out>, chunk=<optimized out>, ptr=<optimized out>, mapelm=<optimized out>) at jemalloc_arena.c:1717 1717 bin->stats.allocated -= size; (gdb) bt #0 0x00000008025bde2c in __jemalloc_arena_dalloc_bin_locked (arena=<optimized out>, chunk=<optimized out>, ptr=<optimized out>, mapelm=<optimized out>) at jemalloc_arena.c:1717 #1 0x00000008025be1cf in __jemalloc_arena_dalloc_bin (chunk=<optimized out>, pageind=<optimized out>, mapelm=<optimized out>, arena=<optimized out>, chunk=<optimized out>, ptr=<optimized out>, pageind=<optimized out>, mapelm=<optimized out>) at jemalloc_arena.c:1733 #2 __jemalloc_arena_dalloc_small (arena=0x4343434343434341, chunk=0x803800000, ptr=0x0, pageind=<optimized out>) at jemalloc_arena.c:1749 #3 0x00000008025c99c5 in __jemalloc_arena_dalloc (arena=<optimized out>, chunk=<optimized out>, ptr=<optimized out>, try_tcache=<optimized out>, arena=<optimized out>, chunk=<optimized out>, ptr=<optimized out>, try_tcache=<optimized out>) at /usr/src/lib/libc/../../contrib/jemalloc/include/jemalloc/internal/arena.h:1005 #4 __jemalloc_idallocx (ptr=<optimized out>, try_tcache=<optimized out>, ptr=<optimized out>, try_tcache=<optimized out>) at /usr/src/lib/libc/../../contrib/jemalloc/include/jemalloc/internal/jemalloc_internal.h:913 #5 __jemalloc_iqallocx (ptr=<optimized out>, try_tcache=<optimized out>, ptr=<optimized out>, try_tcache=<optimized out>) at /usr/src/lib/libc/../../contrib/jemalloc/include/jemalloc/internal/jemalloc_internal.h:932 #6 __jemalloc_iqalloc (ptr=<optimized out>) at /usr/src/lib/libc/../../contrib/jemalloc/include/jemalloc/internal/jemalloc_internal.h:939 #7 __free (ptr=0x803879060) at jemalloc_jemalloc.c:1277 #8 0x0000000000762b93 in phar_extract_file (overwrite=0 '\000', entry=0x803870540, dest=0x803861018 "out/", dest_len=4, error=0x7fffffffc188) at /home/php/php-7.0.7/ext/phar/phar_object.c:4176 #9 0x0000000000762455 in zim_Phar_extractTo (execute_data=0x803813250, return_value=0x8038131f0) at /home/php/php-7.0.7/ext/phar/phar_object.c:4373 #10 0x0000000000b19529 in ZEND_DO_FCALL_SPEC_HANDLER (execute_data=0x803813030) at Zend/zend_vm_execute.h:842 #11 0x0000000000ad22a4 in execute_ex (ex=0x803813030) at Zend/zend_vm_execute.h:417 #12 0x0000000000ad2da5 in zend_execute (op_array=0x80387b000, return_value=0x0) at Zend/zend_vm_execute.h:458 #13 0x0000000000a28609 in zend_execute_scripts (type=8, retval=0x0, file_count=3) at /home/php/php-7.0.7/Zend/zend.c:1427 #14 0x0000000000951045 in php_execute_script (primary_file=0x7fffffffe868) at /home/php/php-7.0.7/main/main.c:2494 #15 0x0000000000c07896 in do_cli (argc=5, argv=0x7fffffffeb48) at /home/php/php-7.0.7/sapi/cli/php_cli.c:974 #16 0x0000000000c06419 in main (argc=5, argv=0x7fffffffeb48) at /home/php/php-7.0.7/sapi/cli/php_cli.c:1344 (gdb) x/i $rip => 0x8025bde2c <__jemalloc_arena_dalloc_bin_locked+556 at jemalloc_arena.c:1717>:sub QWORD PTR [rbx+0x38],rax (gdb) i r rax 0x8 8 rbx 0x4141414141414141 4702111234474983745 rcx 0x42424243 1111638595 rdx 0x0 0 rsi 0x4343434343434343 4846791580151137091 rdi 0x4343434343434341 4846791580151137089 rbp 0x7fffffffbd70 0x7fffffffbd70 rsp 0x7fffffffbd20 0x7fffffffbd20 r8 0x0 0 r9 0x0 0 r10 0x803879010 34418954256 r11 0x8028c12b0 34402472624 r12 0x0 0 r13 0x803879000 34418954240 r14 0x8028adf44 34402393924 r15 0x8028c1250 34402472528 rip 0x8025bde2c 0x8025bde2c <__jemalloc_arena_dalloc_bin_locked+556 at jemalloc_arena.c:1717> eflags 0x10206 [ PF IF RF ] cs 0x43 67 ss 0x3b 59 ds <unavailable> es <unavailable> fs <unavailable> gs <unavailable> (gdb) -- Hans Jerry Illikainen