Bug #52001 [Com]: Memory allocation problems after using variable variables

From: Date: Sun, 06 Jun 2010 17:06:29 +0000
Subject: Bug #52001 [Com]: Memory allocation problems after using variable variables
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-151132@lists.php.net to get a copy of this message
Edit report at http://bugs.php.net/bug.php?id=52001&edit=1

 ID:               52001
 Comment by:       boldin dot pavel at gmail dot com
 Reported by:      lisio at bk dot ru
 Summary:          Memory allocation problems after using variable
                   variables
 Status:           Open
 Type:             Bug
 Package:          Scripting Engine problem
 Operating System: Linux
 PHP Version:      5.3.2

 New Comment:

I have attached patch. It must be reviewed by professional PHP
developer.

For me it is clearly that call of SEPARATE_ZVAL_TO_MAKE_IS_REF must be
predicated with such a check (and it is done in all other cases).


Previous Comments:
------------------------------------------------------------------------
[2010-06-06 18:38:05] boldin dot pavel at gmail dot com

Finally: bug is at 
                if (opline->extended_value & ZEND_FETCH_MAKE_REF) {
                        SEPARATE_ZVAL_TO_MAKE_IS_REF(retval);
                }

SEPARATE_ZVAL_TO_MAKE_IS_REF seems to ruine *retval (which is
executor_globals.uninitialized_ptr). Then this leads to incorrectly
working zend_send_by_var_helper and incorrect referencing count in
zend_assign_to_variable.

Trying to patch now.

------------------------------------------------------------------------
[2010-06-06 18:08:56] boldin dot pavel at gmail dot com

Version without bug:
(gdb)
zend_send_by_var_helper_SPEC_VAR (execute_data=0x88a28d0)
    at /home/davinchi/php-5.3.2/Zend/zend_vm_execute.h:8257
8257            varptr = _get_zval_ptr_var(&opline->op1, EX(Ts),
&free_op1 TSRMLS_CC);
(gdb)
8259            if (varptr == &EG(uninitialized_zval)) {
(gdb) p varptr
$24 = (zval *) 0x877fd04
(gdb) p &executor_globals.uninitialized_zval
$25 = (zval *) 0x877fd04
(gdb) p executor_globals.uninitialized_zval_ptr
$26 = (zval *) 0x877fd04

And version with bug:
zend_send_by_var_helper_SPEC_VAR (execute_data=0x88a28d0)
    at /home/davinchi/php-5.3.2/Zend/zend_vm_execute.h:8254
8254            zend_op *opline = EX(opline);
(gdb)
8257            varptr = _get_zval_ptr_var(&opline->op1, EX(Ts),
&free_op1 TSRMLS_CC);
(gdb) n
8259            if (varptr == &EG(uninitialized_zval)) {
(gdb) p varptr
$27 = (zval *) 0x8876d8c
(gdb) p &executor_globals.uninitialized_zval
$28 = (zval *) 0x877fd04
(gdb) p executor_globals.uninitialized_zval_ptr
$29 = (zval *) 0x8876d8c


See that uninitialized_zval_ptr dont pointers to the uninitialized_zval
at all!

------------------------------------------------------------------------
[2010-06-06 11:23:47] boldin dot pavel at gmail dot com

Here is the problem: Zend/zend_execution.c line 703 (version 5.3.2):
incorrect reference count (== 1) in case of bug. Should be == 3 and copy
data in 'else' branch.

------------------------------------------------------------------------
[2010-06-06 10:36:36] boldin dot pavel at gmail dot com

More detailed: when you pass off the function, _get_zval_cv_lookup no
longer able to find your CVs, and they are missed. _get_zval_cv_lookup
then returns pointer EG(uninitialized_zval_ptr), which is shared among a
set of values.

So two values are stored in same place. It is essential that this
happens only if you call it with ZEND_FCALL_BY_NAME (i.e. declare after
using) and only if dereferenced value is not first.

------------------------------------------------------------------------
[2010-06-06 10:30:54] boldin dot pavel at gmail dot com

Even more:
f($$var, 0) will also work.
If you declare function before calling it will work too.

Seems like bug in zend_do_pass_params or so on, causing to corruption of
buffer.

These CVs are just missing from the scope (active_symbol_table) after
calling function. Seems like they are removed in middle of code
execution.

------------------------------------------------------------------------


The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at

    http://bugs.php.net/bug.php?id=52001


-- 
Edit this bug report at http://bugs.php.net/bug.php?id=52001&edit=1


Thread (12 messages)

« previous php.bugs (#151132) next »