php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #52772 var_dump() doesn't check for the existence of get_class_name before calling it
Submitted: 2010-09-04 03:03 UTC Modified: 2010-09-13 22:14 UTC
From: cataphract@php.net Assigned: kalle (profile)
Status: Closed Package: Variables related
PHP Version: trunk-SVN-2010-09-04 (snap) OS: Windows
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: cataphract@php.net
New email:
PHP Version: OS:

 

 [2010-09-04 03:03 UTC] cataphract@php.net
Description:
------------
php_var_dump has a NULL pointer dereference in var.c:136

Z_OBJ_HANDLER(**struc, get_class_name)(*struc, &class_name, &class_name_len, 0 TSRMLS_CC);

It doesn't check the existence of the handler get_class_name before calling. In particular, it will crash when given a proxy object.

The engine always checks for the existence of this handler before calling. See e.g. the definitions of ZEND_FUNCTION(get_parent_class) and zend_print_flat_zval_r:

http://lxr.php.net/search?q=%22ZEND_FUNCTION%28get_parent_class%29%22&project=PHP_TRUNK&defs=&refs=&path=&hist=
http://lxr.php.net/search?q=zend_print_flat_zval_r&project=PHP_TRUNK&defs=&refs=&path=&hist=

Test script:
---------------
/* Extension */


typedef struct _proxy_test {
	zend_object std;
	long value;
} proxy_test;
static zend_class_entry *pt_ce_ptr;
static zend_object_handlers p_obj_handlers;
static zend_object_value p_ce_create_object(zend_class_entry *class_type TSRMLS_DC)
{
    zend_object_value zov;
    proxy_test       *pobj;

    pobj = emalloc(sizeof *pobj);
    zend_object_std_init((zend_object *) pobj, class_type TSRMLS_CC);
	pobj->value = 7;

    object_properties_init(&pobj->std, class_type);
    zov.handle = zend_objects_store_put(pobj,
        (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 = &p_obj_handlers;
    return zov;
}
zval *p_read_property(zval *object, zval *member, int type, const struct _zend_literal *key TSRMLS_DC)
{
	proxy_test *iobj = zend_object_store_get_object(object TSRMLS_CC);
	if (type == BP_VAR_W || type == BP_VAR_RW || type == BP_VAR_UNSET) {
		zval *ret = zend_object_create_proxy(object, member TSRMLS_CC);
		Z_DELREF_P(ret);
		return ret;
	} else {
		zval *ret;
		MAKE_STD_ZVAL(ret);
		ZVAL_LONG(ret, iobj->value);
		Z_DELREF_P(ret);
		return ret;
	}
}

void p_write_property(zval *object, zval *member, zval *value, const struct _zend_literal *key TSRMLS_DC)
{
	proxy_test *iobj = zend_object_store_get_object(object TSRMLS_CC);
	if (Z_TYPE_P(value) == IS_LONG) {
		iobj->value = Z_LVAL_P(value);
	}
}
zval **p_get_property_ptr_ptr(zval *object, zval *member, const struct _zend_literal *key TSRMLS_DC)
{
	return NULL;
}

/*static zend_function_entry proxy_test_methods[] = {
	{NULL, NULL, NULL, 0, 0}
};*/

ZEND_MODULE_STARTUP_D(testext)
{
	zend_class_entry ce;

	INIT_CLASS_ENTRY(ce, "ProxyTestClass", NULL);
	pt_ce_ptr = zend_register_internal_class(&ce TSRMLS_CC);
	pt_ce_ptr->create_object = p_ce_create_object;
    memcpy(&p_obj_handlers, zend_get_std_object_handlers(), sizeof p_obj_handlers);
	/* could be NULL, but an empty impl is better (see bug #51768) */
	p_obj_handlers.get_property_ptr_ptr = p_get_property_ptr_ptr;
	p_obj_handlers.read_property = p_read_property;
	p_obj_handlers.write_property = p_write_property;
}

/* Script */

<?php

$n = new ProxyTestClass();
$h =& $n->whatever;
var_dump($h); NULL-pointer dereference on handler get_class_name

Expected result:
----------------
No crash. Possibly, var_dump could show "proxy object" and show the zval returned by the get handler or it could just fail.

Actual result:
--------------
 	00000000()	
>	php5ts_debug.dll!php_var_dump(_zval_struct * * struc=0x010a22a8, int level=1, void * * * tsrm_ls=0x00fc4bf8)  Line 136 + 0x23 bytes	C
 	php5ts_debug.dll!zif_var_dump(int ht=1, _zval_struct * return_value=0x010bf3f0, _zval_struct * * return_value_ptr=0x00000000, _zval_struct * this_ptr=0x00000000, int return_value_used=0, void * * * tsrm_ls=0x00fc4bf8)  Line 181 + 0x15 bytes	C
 	php5ts_debug.dll!zend_do_fcall_common_helper_SPEC(_zend_execute_data * execute_data=0x010a20d8, void * * * tsrm_ls=0x00fc4bf8)  Line 638 + 0x5f bytes	C
 	php5ts_debug.dll!ZEND_DO_FCALL_SPEC_CONST_HANDLER(_zend_execute_data * execute_data=0x010a20d8, void * * * tsrm_ls=0x00fc4bf8)  Line 2018	C
 	php5ts_debug.dll!execute(_zend_op_array * op_array=0x010c0dc8, void * * * tsrm_ls=0x00fc4bf8)  Line 410 + 0x11 bytes	C
 	php5ts_debug.dll!zend_execute_scripts(int type=8, void * * * tsrm_ls=0x00fc4bf8, _zval_struct * * retval=0x00000000, int file_count=3, ...)  Line 1193 + 0x21 bytes	C
 	php5ts_debug.dll!php_execute_script(_zend_file_handle * primary_file=0x0095fb48, void * * * tsrm_ls=0x00fc4bf8)  Line 2330 + 0x1b bytes	C
 	php.exe!main(int argc=2, char * * argv=0x00fc4af8)  Line 1252 + 0x13 bytes	C
 	php.exe!__tmainCRTStartup()  Line 555 + 0x19 bytes	C
 	php.exe!mainCRTStartup()  Line 371	C


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-09-13 22:14 UTC] kalle@php.net
Automatic comment from SVN on behalf of kalle
Revision: http://svn.php.net/viewvc/?view=revision&amp;revision=303330
Log: Fixed bug #52772 (var_dump() doesn't check for the existence of get_class_name before calling it)
 [2010-09-13 22:14 UTC] kalle@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: kalle
 [2010-09-13 22:14 UTC] kalle@php.net
This bug has been fixed in SVN.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.
 
Thank you for the report, and for helping us make PHP better.

Fixed in 5.2, 5.3 and trunk :)
 [2010-09-13 23:54 UTC] pajoye@php.net
Automatic comment from SVN on behalf of pajoye
Revision: http://svn.php.net/viewvc/?view=revision&amp;revision=303332
Log: - fix build introduced by fix for #52772
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 21 17:01:58 2024 UTC