From:             cataphract
Operating system: Windows
PHP version:      5.3.2
Package:          Reproducible crash
Bug Type:         Bug
Bug description:Fallback to read_property causes subsequent crash

Description:
------------
When the get_property_ptr_ptr handler is omitted,
zend_fetch_property_address falls back to read_property, but then the
behavior in cases such as

$a = &$obj->prop;

deviates from that of

$a = &$obj['prop'];

which properly emits an error.

The final result is a crash.





Test script:
---------------
exttest.h:



#ifndef PHP_EXTTEST_H

# define PHP_EXTTEST_H

# ifdef HAVE_CONFIG_H

#  include<config.h>

# endif

# include<php.h>

extern zend_module_entry exttest_module_entry;

#define phpext_exttest_ptr &exttest_module_entry

#endif



exttest.c:

#include "exttest.h"



static zend_object_handlers object_handlers;



static zend_object_value ce_create_object(zend_class_entry *class_type
TSRMLS_DC)

{

    zend_object_value zov;

    zend_object       *zobj;



    zobj = emalloc(sizeof *zobj);

    zend_object_std_init(zobj, class_type TSRMLS_CC);



    zend_hash_copy(zobj->properties, &(class_type->default_properties),

        (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval*));

    zov.handle = zend_objects_store_put(zobj,

        (zend_objects_store_dtor_t) zend_objects_destroy_object,

        (zend_objects_free_object_storage_t)
zend_objects_free_object_storage,

        NULL TSRMLS_CC);

    zov.handlers = &object_handlers;

    return zov;

}



ZEND_MODULE_STARTUP_D(exttest)

{

    zend_class_entry ce;

    zend_class_entry *ce_ptr;

    zval *property;



    ALLOC_PERMANENT_ZVAL(property);

    INIT_ZVAL(*property);

    Z_TYPE_P(property) = IS_LONG;

    Z_LVAL_P(property) = 20l;



    memcpy(&object_handlers, zend_get_std_object_handlers(),

        sizeof object_handlers);

    object_handlers.get_property_ptr_ptr = NULL;



    INIT_CLASS_ENTRY(ce, "TestClass", NULL);

    ce_ptr = zend_register_internal_class(&ce TSRMLS_CC);

    ce_ptr->create_object = ce_create_object;

    zend_declare_property_ex(ce_ptr, "prop", 4, property, ZEND_ACC_PUBLIC,

        NULL, 0 TSRMLS_CC);

}



zend_module_entry exttest_module_entry = {

    STANDARD_MODULE_HEADER,

    "exttest",

    NULL, /* Functions */

    ZEND_MODULE_STARTUP_N(exttest) , /* MINIT */

    NULL, /* MSHUTDOWN */

    NULL, /* RINIT */

    NULL, /* RSHUTDOWN */

    NULL, /* MINFO */

    NO_VERSION_YET,

    STANDARD_MODULE_PROPERTIES

};



ZEND_GET_MODULE(exttest)



config.m4:

PHP_ARG_ENABLE(exttest,

  [Whether to enable the "exttest" extension],

  [  enable-exttest         Enable "exttest" extension support])



if test $PHP_EXTTEST != "no"; then

  PHP_SUBST(EXTTEST_SHARED_LIBADD)

  PHP_NEW_EXTENSION(exttest, exttest.c, $ext_shared)

fi





test.php:

<?php

$obj = new TestClass();

debug_zval_dump($obj);

$a = &$obj->prop;

debug_zval_dump($obj);

debug_zval_dump(&$a);

$a = 40;

debug_zval_dump($obj);

debug_zval_dump(&$a);

unset($a);

debug_zval_dump($obj);



Expected result:
----------------
Expected an error saying the operation is not permitted (like when
attempting $a = &obj['index'] where there's no get_property_ptr_ptr
equivalent).

Actual result:
--------------
When thre's get_property_ptr_ptr:



object(TestClass)#1 (1) refcount(2){

  ["prop"]=>

  long(20) refcount(2)

}

object(TestClass)#1 (1) refcount(2){

  ["prop"]=>

  &long(20) refcount(2)

}

&long(20) refcount(3)

object(TestClass)#1 (1) refcount(2){

  ["prop"]=>

  &long(40) refcount(2)

}

&long(40) refcount(3)

object(TestClass)#1 (1) refcount(2){

  ["prop"]=>

  long(40) refcount(1)

}



When there's no get_property_ptr_ptr, zend_fetch_property_address falls
back to read_propert. Something happens afterwards that provokes the
crash.



object(TestClass)#1 (1) refcount(2){

  ["prop"]=>

  long(20) refcount(2)

}

object(TestClass)#1 (1) refcount(2){

  ["prop"]=>

  long(20) refcount(1)

}

&long(20) refcount(3)

object(TestClass)#1 (1) refcount(2){

  ["prop"]=>

  long(20) refcount(1)

}

&long(40) refcount(3)

object(TestClass)#1 (1) refcount(2){

  ["prop"]=>

  long(20) refcount(1)

}

Segmentation fault



#0  0x081d60ae in zend_mm_check_ptr (heap=0x83881b8, ptr=0x840ca90,
silent=1,

    __zend_filename=0x83633a0
"/home/glopes/php/php-5.3.2/Zend/zend_variables.c", __zend_lineno=178,

    __zend_orig_filename=0x83621b8
"/home/glopes/php/php-5.3.2/Zend/zend_execute_API.c",

    __zend_orig_lineno=440) at
/home/glopes/php/php-5.3.2/Zend/zend_alloc.c:1347

#1  0x081d768d in _zend_mm_free_int (heap=0x83881b8, p=0x840ca90,

    __zend_filename=0x83633a0
"/home/glopes/php/php-5.3.2/Zend/zend_variables.c", __zend_lineno=178,

    __zend_orig_filename=0x83621b8
"/home/glopes/php/php-5.3.2/Zend/zend_execute_API.c",

    __zend_orig_lineno=440) at
/home/glopes/php/php-5.3.2/Zend/zend_alloc.c:1983

#2  0x081d86bb in _efree (ptr=0x840ca90,

    __zend_filename=0x83633a0
"/home/glopes/php/php-5.3.2/Zend/zend_variables.c", __zend_lineno=178,

    __zend_orig_filename=0x83621b8
"/home/glopes/php/php-5.3.2/Zend/zend_execute_API.c",

    __zend_orig_lineno=440) at
/home/glopes/php/php-5.3.2/Zend/zend_alloc.c:2351

#3  0x081e9944 in _zval_ptr_dtor (zval_ptr=0x841d584,

    __zend_filename=0x83633a0
"/home/glopes/php/php-5.3.2/Zend/zend_variables.c", __zend_lineno=178)

    at /home/glopes/php/php-5.3.2/Zend/zend_execute_API.c:440

#4  0x081f7ca8 in _zval_ptr_dtor_wrapper (zval_ptr=0x841d584)

    at /home/glopes/php/php-5.3.2/Zend/zend_variables.c:178

#5  0x08207cf7 in zend_hash_destroy (ht=0x841d520) at
/home/glopes/php/php-5.3.2/Zend/zend_hash.c:526

#6  0x0821d64d in zend_object_std_dtor (object=0x841ccf8)

    at /home/glopes/php/php-5.3.2/Zend/zend_objects.c:45

#7  0x0821d9a9 in zend_objects_free_object_storage (object=0x841ccf8)

    at /home/glopes/php/php-5.3.2/Zend/zend_objects.c:114

#8  0x0822252b in zend_objects_store_del_ref_by_handle_ex (handle=1,
handlers=0xb7f1bd60)

    at /home/glopes/php/php-5.3.2/Zend/zend_objects_API.c:220

#9  0x08222320 in zend_objects_store_del_ref (zobject=0x841c45c)

    at /home/glopes/php/php-5.3.2/Zend/zend_objects_API.c:172

#10 0x081f7917 in _zval_dtor_func (zvalue=0x841c45c,

    __zend_filename=0x83621b8
"/home/glopes/php/php-5.3.2/Zend/zend_execute_API.c", __zend_lineno=439)

    at /home/glopes/php/php-5.3.2/Zend/zend_variables.c:52

#11 0x081e96cf in _zval_dtor (zvalue=0x841c45c,

    __zend_filename=0x83621b8
"/home/glopes/php/php-5.3.2/Zend/zend_execute_API.c", __zend_lineno=439)

    at /home/glopes/php/php-5.3.2/Zend/zend_variables.h:35

#12 0x081e9919 in _zval_ptr_dtor (zval_ptr=0x841d5d8,

    __zend_filename=0x83633a0
"/home/glopes/php/php-5.3.2/Zend/zend_variables.c", __zend_lineno=178)

    at /home/glopes/php/php-5.3.2/Zend/zend_execute_API.c:439

#13 0x081f7ca8 in _zval_ptr_dtor_wrapper (zval_ptr=0x841d5d8)

    at /home/glopes/php/php-5.3.2/Zend/zend_variables.c:178

#14 0x0820806e in zend_hash_apply_deleter (ht=0x83879d0, p=0x841d5cc)

    at /home/glopes/php/php-5.3.2/Zend/zend_hash.c:611

#15 0x08208596 in zend_hash_reverse_apply (ht=0x83879d0,
apply_func=0x81e91bd <zval_call_destructor>)

    at /home/glopes/php/php-5.3.2/Zend/zend_hash.c:760

#16 0x081e924a in shutdown_destructors () at
/home/glopes/php/php-5.3.2/Zend/zend_execute_API.c:226

#17 0x081f943c in zend_call_destructors () at
/home/glopes/php/php-5.3.2/Zend/zend.c:874

#18 0x08190427 in php_request_shutdown (dummy=0x0) at
/home/glopes/php/php-5.3.2/main/main.c:1587

#19 0x082c0086 in main (argc=2, argv=0xbfffe674) at
/home/glopes/php/php-5.3.2/sapi/cli/php_cli.c:1373



-- 
Edit bug report at http://bugs.php.net/bug.php?id=51768&edit=1
-- 
Try a snapshot (PHP 5.2):            
http://bugs.php.net/fix.php?id=51768&r=trysnapshot52
Try a snapshot (PHP 5.3):            
http://bugs.php.net/fix.php?id=51768&r=trysnapshot53
Try a snapshot (PHP 6.0):            
http://bugs.php.net/fix.php?id=51768&r=trysnapshot60
Fixed in SVN:                        
http://bugs.php.net/fix.php?id=51768&r=fixed
Fixed in SVN and need be documented: 
http://bugs.php.net/fix.php?id=51768&r=needdocs
Fixed in release:                    
http://bugs.php.net/fix.php?id=51768&r=alreadyfixed
Need backtrace:                      
http://bugs.php.net/fix.php?id=51768&r=needtrace
Need Reproduce Script:               
http://bugs.php.net/fix.php?id=51768&r=needscript
Try newer version:                   
http://bugs.php.net/fix.php?id=51768&r=oldversion
Not developer issue:                 
http://bugs.php.net/fix.php?id=51768&r=support
Expected behavior:                   
http://bugs.php.net/fix.php?id=51768&r=notwrong
Not enough info:                     
http://bugs.php.net/fix.php?id=51768&r=notenoughinfo
Submitted twice:                     
http://bugs.php.net/fix.php?id=51768&r=submittedtwice
register_globals:                    
http://bugs.php.net/fix.php?id=51768&r=globals
PHP 4 support discontinued:          http://bugs.php.net/fix.php?id=51768&r=php4
Daylight Savings:                    http://bugs.php.net/fix.php?id=51768&r=dst
IIS Stability:                       
http://bugs.php.net/fix.php?id=51768&r=isapi
Install GNU Sed:                     
http://bugs.php.net/fix.php?id=51768&r=gnused
Floating point limitations:          
http://bugs.php.net/fix.php?id=51768&r=float
No Zend Extensions:                  
http://bugs.php.net/fix.php?id=51768&r=nozend
MySQL Configuration Error:           
http://bugs.php.net/fix.php?id=51768&r=mysqlcfg

Reply via email to