Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Invalid read/segfault on specific input #177

Open
michael-grunder opened this issue Nov 3, 2024 · 0 comments
Open

Invalid read/segfault on specific input #177

michael-grunder opened this issue Nov 3, 2024 · 0 comments

Comments

@michael-grunder
Copy link

Hi again 👋,

I found a flaw in msgpack on a specific input string.

Very easy to reproducer:

<?php
$data = hex2bin('de06000000c09baa316e3b303e66656367675203060657545563343864643600000000');
$unserilized = msgpack_unserialize($data);

With the zend allocator:

 valgrind sapi/cli/php unserialize.php
==3142543== Memcheck, a memory error detector
==3142543== Copyright (C) 2002-2024, and GNU GPL'd, by Julian Seward et al.
==3142543== Using Valgrind-3.23.0 and LibVEX; rerun with -h for copyright info
==3142543== Command: sapi/cli/php unserialize.php
==3142543==
==3142543== Warning: set address range perms: large range [0x59c95000, 0xd9c95000) (defined)
==3142543== Warning: set address range perms: large range [0x59c96000, 0xd9c95000) (undefined)

Warning: [msgpack] (php_msgpack_unserialize) Insufficient data for unserializing in /home/mike/dev/phpfarm/src/php-8.3.11-debug/unserialize.php on line 4
php: /home/mike/dev/phpfarm/src/php-8.3.11-debug/Zend/zend_gc.c:698: gc_possible_root: Assertion `zval_gc_type((ref)->gc.u.type_info) == 7 || zval_gc_type((ref)->gc.u.type_info) == 8' failed.
==3142543==
==3142543== Process terminating with default action of signal 6 (SIGABRT)
==3142543==    at 0x5E009FC: __pthread_kill_implementation (pthread_kill.c:44)
==3142543==    by 0x5E009FC: __pthread_kill_internal (pthread_kill.c:78)
==3142543==    by 0x5E009FC: pthread_kill@@GLIBC_2.34 (pthread_kill.c:89)
==3142543==    by 0x5DAC475: raise (raise.c:26)
==3142543==    by 0x5D927F2: abort (abort.c:79)
==3142543==    by 0x5D9271A: __assert_fail_base.cold (assert.c:92)
==3142543==    by 0x5DA3E95: __assert_fail (assert.c:101)
==3142543==    by 0xEA5570: gc_possible_root (zend_gc.c:698)
==3142543==    by 0xDD50CA: gc_check_possible_root (zend_gc.h:98)
==3142543==    by 0xDD511C: i_zval_ptr_dtor (zend_variables.h:46)
==3142543==    by 0xDD52EB: zval_ptr_dtor (zend_variables.c:84)
==3142543==    by 0x8C9D3B: msgpack_unserialize_var_destroy (msgpack_unpack.c:364)
==3142543==    by 0x8C4DB9: php_msgpack_unserialize (msgpack.c:279)
==3142543==    by 0x8C4F2D: zif_msgpack_unserialize (msgpack.c:318)
==3142543==
==3142543== HEAP SUMMARY:
==3142543==     in use at exit: 3,418,965 bytes in 27,735 blocks
==3142543==   total heap usage: 30,680 allocs, 2,944 frees, 2,151,772,892 bytes allocated
==3142543==
==3142543== LEAK SUMMARY:
==3142543==    definitely lost: 34,983 bytes in 986 blocks
==3142543==    indirectly lost: 40 bytes in 1 blocks
==3142543==      possibly lost: 2,619,303 bytes in 21,628 blocks
==3142543==    still reachable: 2,148,244,191 bytes in 5,121 blocks
==3142543==         suppressed: 0 bytes in 0 blocks
==3142543== Rerun with --leak-check=full to see details of leaked memory
==3142543==
==3142543== For lists of detected and suppressed errors, rerun with: -s
==3142543== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
[1]    3142543 IOT instruction (core dumped)  valgrind sapi/cli/php unserialize.php

Without the allocator:

 USE_ZEND_ALLOC=0 valgrind sapi/cli/php unserialize.php
==3142751== Memcheck, a memory error detector
==3142751== Copyright (C) 2002-2024, and GNU GPL'd, by Julian Seward et al.
==3142751== Using Valgrind-3.23.0 and LibVEX; rerun with -h for copyright info
==3142751== Command: sapi/cli/php unserialize.php
==3142751==
==3142751== Warning: set address range perms: large range [0x59c95000, 0xd9c95000) (defined)
==3142751== Warning: set address range perms: large range [0x59c96000, 0xd9c95000) (undefined)

Warning: [msgpack] (php_msgpack_unserialize) Insufficient data for unserializing in /home/mike/dev/phpfarm/src/php-8.3.11-debug/unserialize.php on line 4
==3142751== Invalid read of size 4
==3142751==    at 0xDD4E45: zend_gc_delref (zend_types.h:1342)
==3142751==    by 0xDD50FE: i_zval_ptr_dtor (zend_variables.h:43)
==3142751==    by 0xDD52EB: zval_ptr_dtor (zend_variables.c:84)
==3142751==    by 0x8C9D3B: msgpack_unserialize_var_destroy (msgpack_unpack.c:364)
==3142751==    by 0x8C4DB9: php_msgpack_unserialize (msgpack.c:279)
==3142751==    by 0x8C4F2D: zif_msgpack_unserialize (msgpack.c:318)
==3142751==    by 0xE18658: ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER (zend_vm_execute.h:1337)
==3142751==    by 0xE8E113: execute_ex (zend_vm_execute.h:57216)
==3142751==    by 0xE92959: zend_execute (zend_vm_execute.h:61604)
==3142751==    by 0xDD9AAA: zend_execute_scripts (zend.c:1891)
==3142751==    by 0xD37F82: php_execute_script (main.c:2528)
==3142751==    by 0xF4C25A: do_cli (php_cli.c:966)
==3142751==  Address 0xa07ee50 is 0 bytes inside a block of size 56 free'd
==3142751==    at 0x484C9F4: free (vg_replace_malloc.c:989)
==3142751==    by 0xD9AF5D: _efree_custom (zend_alloc.c:2500)
==3142751==    by 0xD9B0A8: _efree (zend_alloc.c:2620)
==3142751==    by 0xDF2F95: zend_array_destroy (zend_hash.c:1867)
==3142751==    by 0xDD517A: rc_dtor_func (zend_variables.c:57)
==3142751==    by 0xDD510E: i_zval_ptr_dtor (zend_variables.h:44)
==3142751==    by 0xDD52EB: zval_ptr_dtor (zend_variables.c:84)
==3142751==    by 0x8CADD3: msgpack_unserialize_map_item (msgpack_unpack.c:647)
==3142751==    by 0x8C4511: msgpack_unserialize_execute (unpack_template.h:405)
==3142751==    by 0x8C4B9D: php_msgpack_unserialize (msgpack.c:252)
==3142751==    by 0x8C4F2D: zif_msgpack_unserialize (msgpack.c:318)
==3142751==    by 0xE18658: ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER (zend_vm_execute.h:1337)
==3142751==  Block was alloc'd at
==3142751==    at 0x484977B: malloc (vg_replace_malloc.c:446)
==3142751==    by 0xD9C29B: __zend_malloc (zend_alloc.c:3128)
==3142751==    by 0xD9AEF0: _malloc_custom (zend_alloc.c:2491)
==3142751==    by 0xD9B02E: _emalloc (zend_alloc.c:2610)
==3142751==    by 0xDEDEC9: _zend_new_array (zend_hash.c:291)
==3142751==    by 0x8CA788: msgpack_unserialize_array (msgpack_unpack.c:550)
==3142751==    by 0x8C39BA: msgpack_unserialize_execute (unpack_template.h:231)
==3142751==    by 0x8C4B9D: php_msgpack_unserialize (msgpack.c:252)
==3142751==    by 0x8C4F2D: zif_msgpack_unserialize (msgpack.c:318)
==3142751==    by 0xE18658: ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER (zend_vm_execute.h:1337)
==3142751==    by 0xE8E113: execute_ex (zend_vm_execute.h:57216)
==3142751==    by 0xE92959: zend_execute (zend_vm_execute.h:61604)
==3142751==
php: /home/mike/dev/phpfarm/src/php-8.3.11-debug/Zend/zend_types.h:1342: zend_gc_delref: Assertion `p->refcount > 0' failed.
==3142751==
==3142751== Process terminating with default action of signal 6 (SIGABRT)
==3142751==    at 0x5E009FC: __pthread_kill_implementation (pthread_kill.c:44)
==3142751==    by 0x5E009FC: __pthread_kill_internal (pthread_kill.c:78)
==3142751==    by 0x5E009FC: pthread_kill@@GLIBC_2.34 (pthread_kill.c:89)
==3142751==    by 0x5DAC475: raise (raise.c:26)
==3142751==    by 0x5D927F2: abort (abort.c:79)
==3142751==    by 0x5D9271A: __assert_fail_base.cold (assert.c:92)
==3142751==    by 0x5DA3E95: __assert_fail (assert.c:101)
==3142751==    by 0xDD4E63: zend_gc_delref (zend_types.h:1342)
==3142751==    by 0xDD50FE: i_zval_ptr_dtor (zend_variables.h:43)
==3142751==    by 0xDD52EB: zval_ptr_dtor (zend_variables.c:84)
==3142751==    by 0x8C9D3B: msgpack_unserialize_var_destroy (msgpack_unpack.c:364)
==3142751==    by 0x8C4DB9: php_msgpack_unserialize (msgpack.c:279)
==3142751==    by 0x8C4F2D: zif_msgpack_unserialize (msgpack.c:318)
==3142751==    by 0xE18658: ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER (zend_vm_execute.h:1337)
==3142751==
==3142751== HEAP SUMMARY:
==3142751==     in use at exit: 3,854,817 bytes in 27,959 blocks
==3142751==   total heap usage: 31,192 allocs, 3,232 frees, 2,152,369,935 bytes allocated
==3142751==
==3142751== LEAK SUMMARY:
==3142751==    definitely lost: 34,983 bytes in 986 blocks
==3142751==    indirectly lost: 40 bytes in 1 blocks
==3142751==      possibly lost: 2,679,753 bytes in 21,820 blocks
==3142751==    still reachable: 2,148,619,593 bytes in 5,153 blocks
==3142751==         suppressed: 0 bytes in 0 blocks
==3142751== Rerun with --leak-check=full to see details of leaked memory
==3142751==
==3142751== For lists of detected and suppressed errors, rerun with: -s
==3142751== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
[1]    3142751 IOT instruction (core dumped)  USE_ZEND_ALLOC=0 valgrind sapi/cli/php unserialize.php

I can replicate the problem both in debug and release builds of PHP. I'm using 8.3.11 here though.

PHP 8.3.11 (cli) (built: Aug 30 2024 09:27:49) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.3.11, Copyright (c) Zend Technologies
    with Zend OPcache v8.3.11, Copyright (c), by Zend Technologies

Let me know if I can provide any other info.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant