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

[BUG] Memory corruption in zim_Phalcon_Security_hash() #1340

Closed
ghost opened this issue Oct 7, 2013 · 2 comments
Closed

[BUG] Memory corruption in zim_Phalcon_Security_hash() #1340

ghost opened this issue Oct 7, 2013 · 2 comments

Comments

@ghost
Copy link

ghost commented Oct 7, 2013

Test case:

<?php
$s = new \Phalcon\Security();
$s->setWorkFactor("10");
echo $s->hash('password', null), PHP_EOL;
?>

when run under valgrind

==9971== Invalid read of size 4
==9971==    at 0xA6CA09: zval_delref_p (zend.h:409)
==9971==    by 0xA6DD66: i_zval_ptr_dtor (zend_execute.h:76)
==9971==    by 0xA6E618: zend_vm_stack_clear_multiple (zend_execute.h:298)
==9971==    by 0xA757E0: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:642)
==9971==    by 0xA759B1: ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER (zend_vm_execute.h:685)
==9971==    by 0xA7424D: execute_ex (zend_vm_execute.h:363)
==9971==    by 0xA74332: zend_execute (zend_vm_execute.h:388)
==9971==    by 0xA2EC67: zend_execute_scripts (zend.c:1318)
==9971==    by 0x96F9EB: php_execute_script (main.c:2489)
==9971==    by 0xAEF368: do_cli (php_cli.c:994)
==9971==    by 0xAF099F: main (php_cli.c:1378)
==9971==  Address 0x114276d0 is 16 bytes inside a block of size 32 free'd
==9971==    at 0x4A08A6C: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9971==    by 0x9E8A4C: _efree (zend_alloc.c:2437)
==9971==    by 0xA13ACD: i_zval_ptr_dtor (zend_execute.h:82)
==9971==    by 0xA15C92: _zval_ptr_dtor (zend_execute_API.c:426)
==9971==    by 0xBBC6737: zim_Phalcon_Security_hash (security.c:236)
==9971==    by 0xB97911A: phalcon_execute_internal (phalcon.c:371)
==9971==    by 0xA74F4E: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:552)
==9971==    by 0xA759B1: ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER (zend_vm_execute.h:685)
==9971==    by 0xA7424D: execute_ex (zend_vm_execute.h:363)
==9971==    by 0xA74332: zend_execute (zend_vm_execute.h:388)
==9971==    by 0xA2EC67: zend_execute_scripts (zend.c:1318)
==9971==    by 0x96F9EB: php_execute_script (main.c:2489)
==9971== 
==9971== Invalid write of size 4
==9971==    at 0xA6CA13: zval_delref_p (zend.h:409)
==9971==    by 0xA6DD66: i_zval_ptr_dtor (zend_execute.h:76)
==9971==    by 0xA6E618: zend_vm_stack_clear_multiple (zend_execute.h:298)
==9971==    by 0xA757E0: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:642)
==9971==    by 0xA759B1: ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER (zend_vm_execute.h:685)
==9971==    by 0xA7424D: execute_ex (zend_vm_execute.h:363)
==9971==    by 0xA74332: zend_execute (zend_vm_execute.h:388)
==9971==    by 0xA2EC67: zend_execute_scripts (zend.c:1318)
==9971==    by 0x96F9EB: php_execute_script (main.c:2489)
==9971==    by 0xAEF368: do_cli (php_cli.c:994)
==9971==    by 0xAF099F: main (php_cli.c:1378)
==9971==  Address 0x114276d0 is 16 bytes inside a block of size 32 free'd
==9971==    at 0x4A08A6C: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9971==    by 0x9E8A4C: _efree (zend_alloc.c:2437)
==9971==    by 0xA13ACD: i_zval_ptr_dtor (zend_execute.h:82)
==9971==    by 0xA15C92: _zval_ptr_dtor (zend_execute_API.c:426)
==9971==    by 0xBBC6737: zim_Phalcon_Security_hash (security.c:236)
==9971==    by 0xB97911A: phalcon_execute_internal (phalcon.c:371)
==9971==    by 0xA74F4E: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:552)
==9971==    by 0xA759B1: ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER (zend_vm_execute.h:685)
==9971==    by 0xA7424D: execute_ex (zend_vm_execute.h:363)
==9971==    by 0xA74332: zend_execute (zend_vm_execute.h:388)
==9971==    by 0xA2EC67: zend_execute_scripts (zend.c:1318)
==9971==    by 0x96F9EB: php_execute_script (main.c:2489)
==9971== 
==9971== Invalid read of size 4
==9971==    at 0xA6CA1A: zval_delref_p (zend.h:409)
==9971==    by 0xA6DD66: i_zval_ptr_dtor (zend_execute.h:76)
==9971==    by 0xA6E618: zend_vm_stack_clear_multiple (zend_execute.h:298)
==9971==    by 0xA757E0: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:642)
==9971==    by 0xA759B1: ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER (zend_vm_execute.h:685)
==9971==    by 0xA7424D: execute_ex (zend_vm_execute.h:363)
==9971==    by 0xA74332: zend_execute (zend_vm_execute.h:388)
==9971==    by 0xA2EC67: zend_execute_scripts (zend.c:1318)
==9971==    by 0x96F9EB: php_execute_script (main.c:2489)
==9971==    by 0xAEF368: do_cli (php_cli.c:994)
==9971==    by 0xAF099F: main (php_cli.c:1378)
==9971==  Address 0x114276d0 is 16 bytes inside a block of size 32 free'd
==9971==    at 0x4A08A6C: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9971==    by 0x9E8A4C: _efree (zend_alloc.c:2437)
==9971==    by 0xA13ACD: i_zval_ptr_dtor (zend_execute.h:82)
==9971==    by 0xA15C92: _zval_ptr_dtor (zend_execute_API.c:426)
==9971==    by 0xBBC6737: zim_Phalcon_Security_hash (security.c:236)
==9971==    by 0xB97911A: phalcon_execute_internal (phalcon.c:371)
==9971==    by 0xA74F4E: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:552)
==9971==    by 0xA759B1: ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER (zend_vm_execute.h:685)
==9971==    by 0xA7424D: execute_ex (zend_vm_execute.h:363)
==9971==    by 0xA74332: zend_execute (zend_vm_execute.h:388)
==9971==    by 0xA2EC67: zend_execute_scripts (zend.c:1318)
==9971==    by 0x96F9EB: php_execute_script (main.c:2489)
==9971== 
==9971== Invalid read of size 4
==9971==    at 0xA6C9B8: zval_refcount_p (zend.h:397)
==9971==    by 0xA6DE47: i_zval_ptr_dtor (zend_execute.h:86)
==9971==    by 0xA6E618: zend_vm_stack_clear_multiple (zend_execute.h:298)
==9971==    by 0xA757E0: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:642)
==9971==    by 0xA759B1: ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER (zend_vm_execute.h:685)
==9971==    by 0xA7424D: execute_ex (zend_vm_execute.h:363)
==9971==    by 0xA74332: zend_execute (zend_vm_execute.h:388)
==9971==    by 0xA2EC67: zend_execute_scripts (zend.c:1318)
==9971==    by 0x96F9EB: php_execute_script (main.c:2489)
==9971==    by 0xAEF368: do_cli (php_cli.c:994)
==9971==    by 0xAF099F: main (php_cli.c:1378)
==9971==  Address 0x114276d0 is 16 bytes inside a block of size 32 free'd
==9971==    at 0x4A08A6C: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9971==    by 0x9E8A4C: _efree (zend_alloc.c:2437)
==9971==    by 0xA13ACD: i_zval_ptr_dtor (zend_execute.h:82)
==9971==    by 0xA15C92: _zval_ptr_dtor (zend_execute_API.c:426)
==9971==    by 0xBBC6737: zim_Phalcon_Security_hash (security.c:236)
==9971==    by 0xB97911A: phalcon_execute_internal (phalcon.c:371)
==9971==    by 0xA74F4E: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:552)
==9971==    by 0xA759B1: ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER (zend_vm_execute.h:685)
==9971==    by 0xA7424D: execute_ex (zend_vm_execute.h:363)
==9971==    by 0xA74332: zend_execute (zend_vm_execute.h:388)
==9971==    by 0xA2EC67: zend_execute_scripts (zend.c:1318)
==9971==    by 0x96F9EB: php_execute_script (main.c:2489)
==9971== 
==9971== Invalid read of size 1
==9971==    at 0xA6CA73: gc_zval_check_possible_root (zend_gc.h:182)
==9971==    by 0xA6DE6B: i_zval_ptr_dtor (zend_execute.h:90)
==9971==    by 0xA6E618: zend_vm_stack_clear_multiple (zend_execute.h:298)
==9971==    by 0xA757E0: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:642)
==9971==    by 0xA759B1: ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER (zend_vm_execute.h:685)
==9971==    by 0xA7424D: execute_ex (zend_vm_execute.h:363)
==9971==    by 0xA74332: zend_execute (zend_vm_execute.h:388)
==9971==    by 0xA2EC67: zend_execute_scripts (zend.c:1318)
==9971==    by 0x96F9EB: php_execute_script (main.c:2489)
==9971==    by 0xAEF368: do_cli (php_cli.c:994)
==9971==    by 0xAF099F: main (php_cli.c:1378)
==9971==  Address 0x114276d4 is 20 bytes inside a block of size 32 free'd
==9971==    at 0x4A08A6C: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9971==    by 0x9E8A4C: _efree (zend_alloc.c:2437)
==9971==    by 0xA13ACD: i_zval_ptr_dtor (zend_execute.h:82)
==9971==    by 0xA15C92: _zval_ptr_dtor (zend_execute_API.c:426)
==9971==    by 0xBBC6737: zim_Phalcon_Security_hash (security.c:236)
==9971==    by 0xB97911A: phalcon_execute_internal (phalcon.c:371)
==9971==    by 0xA74F4E: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:552)
==9971==    by 0xA759B1: ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER (zend_vm_execute.h:685)
==9971==    by 0xA7424D: execute_ex (zend_vm_execute.h:363)
==9971==    by 0xA74332: zend_execute (zend_vm_execute.h:388)
==9971==    by 0xA2EC67: zend_execute_scripts (zend.c:1318)
==9971==    by 0x96F9EB: php_execute_script (main.c:2489)
==9971== 
==9971== Invalid read of size 1
==9971==    at 0xA6CA7F: gc_zval_check_possible_root (zend_gc.h:182)
==9971==    by 0xA6DE6B: i_zval_ptr_dtor (zend_execute.h:90)
==9971==    by 0xA6E618: zend_vm_stack_clear_multiple (zend_execute.h:298)
==9971==    by 0xA757E0: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:642)
==9971==    by 0xA759B1: ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER (zend_vm_execute.h:685)
==9971==    by 0xA7424D: execute_ex (zend_vm_execute.h:363)
==9971==    by 0xA74332: zend_execute (zend_vm_execute.h:388)
==9971==    by 0xA2EC67: zend_execute_scripts (zend.c:1318)
==9971==    by 0x96F9EB: php_execute_script (main.c:2489)
==9971==    by 0xAEF368: do_cli (php_cli.c:994)
==9971==    by 0xAF099F: main (php_cli.c:1378)
==9971==  Address 0x114276d4 is 20 bytes inside a block of size 32 free'd
==9971==    at 0x4A08A6C: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9971==    by 0x9E8A4C: _efree (zend_alloc.c:2437)
==9971==    by 0xA13ACD: i_zval_ptr_dtor (zend_execute.h:82)
==9971==    by 0xA15C92: _zval_ptr_dtor (zend_execute_API.c:426)
==9971==    by 0xBBC6737: zim_Phalcon_Security_hash (security.c:236)
==9971==    by 0xB97911A: phalcon_execute_internal (phalcon.c:371)
==9971==    by 0xA74F4E: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:552)
==9971==    by 0xA759B1: ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER (zend_vm_execute.h:685)
==9971==    by 0xA7424D: execute_ex (zend_vm_execute.h:363)
==9971==    by 0xA74332: zend_execute (zend_vm_execute.h:388)
==9971==    by 0xA2EC67: zend_execute_scripts (zend.c:1318)
==9971==    by 0x96F9EB: php_execute_script (main.c:2489)
==9971== 

Possible reason is

    if (!work_factor) {
        PHALCON_INIT_VAR(work_factor);
    } else {
        PHALCON_SEPARATE_PARAM(work_factor);
    }

    if (Z_TYPE_P(work_factor) == IS_NULL) {
        PHALCON_OBS_NVAR(work_factor);
        phalcon_read_property_this(&work_factor, this_ptr, SL("_workFactor"), PH_NOISY_CC);
    }

when Z_TYPE_P(work_factor) == IS_NULL, work_factor gets separated; then PHALCON_OBS_NVAR() registers it in the current memory frame and PHALCON_MM_RESTORE() destroys it and Zend does not expect this (parameters are automatically disposed of by Zend).

@ghost
Copy link
Author

ghost commented Oct 7, 2013

It turned out that separation is irrelevant here — NULL is passed as a temporary variable and its refcount is 1; therefore, PHALCON_SEPARATE_PARAM() isnores it; however, PHALCON_OBS_NVAR() destroys that NULL (zval_ptr_dtor(&z); branch is taken).

The solution is to use PHALCON_OBS_VAR() in such cases.

@ghost
Copy link
Author

ghost commented Oct 8, 2013

I have modified PHALCON_SEPARATE_PARAM() so that it separates the variable with any refcount — this seems to be the only reliable solution.

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

0 participants