Bug #68484 [Opn->Nab]: zend_parse_parameters returns an invalid resource pointer

From: Date: Sun, 23 Nov 2014 10:16:47 +0000
Subject: Bug #68484 [Opn->Nab]: zend_parse_parameters returns an invalid resource pointer
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-188754@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=68484&edit=1 ID: 68484 Updated by: nikic@php.net Reported by: jrhodes at redpointsoftware dot com dot au Summary: zend_parse_parameters returns an invalid resource pointer -Status: Open +Status: Not a bug Type: Bug Package: Reproducible crash Operating System: openSUSE 13 PHP Version: 5.4.35 Block user comment: N Private report: N New Comment: You're using a l (for "long") parameter, but pass an "unsigned int act" to it. On platforms where the size of int and long differ this will cause memory corruption. As arguments are pushed to the stack in reverse order it also affects the resource argument. Previous Comments: ------------------------------------------------------------------------ [2014-11-23 08:45:11] jrhodes at redpointsoftware dot com dot au Description: ------------ Originally reported at https://bugzilla.redhat.com/show_bug.cgi?id=1167069. At first I believed this was an issue with libvirt's PHP bindings, but after further investigation I'm somewhat sure this is a bug in PHP itself. After expanding the parameter parsing call libvirt is making in "libvirt_network_set_active", it is effectively performing: --------------------------------------------- PHP_FUNCTION(libvirt_network_set_active) { php_libvirt_network *network = NULL; zval *znetwork; unsigned int act = 0; reset_error(TSRMLS_C); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &znetwork, &act) == FAILURE) { set_error("Invalid arguments" TSRMLS_CC); RETURN_FALSE; } --------------------------------------------- After receiving a segmentation fault when zend_fetch_resource is called (not shown), I added the following code immediately after the above code snippet: --------------------------------------------- if (znetwork == NULL) { printf("znetwork is NULL.\n"); } else { printf("znetwork is not NULL.\n"); } zend_uchar tt; tt = znetwork->type; --------------------------------------------- Under this scenario, I get a segmentation fault when "type" is accessed (effectively imitating the Z_TYPE_P macro used in zend_fetch_resource). "znetwork is not NULL." is printed out, indicating the pointer is not null, but is also not valid. However, when I change the parameter signature from "rl" to "rb", like so: --------------------------------------------- PHP_FUNCTION(libvirt_network_set_active) { php_libvirt_network *network = NULL; zval *znetwork; zend_bool act = 0; reset_error(TSRMLS_C); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rb", &znetwork, &act) == FAILURE) { set_error("Invalid arguments" TSRMLS_CC); RETURN_FALSE; } --------------------------------------------- the segmentation fault no longer occurs. This indicates that the source of invalid resource pointer is impacted by the type of the second parameter. Test script: --------------- <?php $conn = libvirt_connect('connection_uri', false); $network = libvirt_network_get($conn, 'network_name_here'); // This will return an error stating that it expected 2 parameters (the // documentation states it only accepts 1 parameter, but that doesn't // make much sense for this function call). libvirt_network_set_active($network); // Both of these calls will cause a segmentation fault. libvirt_network_set_active($network, true); libvirt_network_set_active($network, 1); ?> Expected result: ---------------- libvirt's PHP extension should not crash (and perform it's expected behaviour). Actual result: -------------- Warning: libvirt_network_set_active() expects exactly 2 parameters, 1 given in /home/james/Projects/Phabricator/libvirt_tests/active_network.php on line 10 Warning: libvirt_network_set_active(): Invalid arguments in /home/james/Projects/Phabricator/libvirt_tests/active_network.php on line 10 Program received signal SIGSEGV, Segmentation fault. 0x000000000068bd4c in zend_fetch_resource (passed_id=passed_id@entry=0x7fffffffa228, default_id=default_id@entry=-1, resource_type_name=resource_type_name@entry=0x7ffff6092cb1 "Libvirt virtual network", found_resource_type=found_resource_type@entry=0x0, num_resource_types=num_resource_types@entry=1) at /root/php-5.4.35/Zend/zend_list.c:126 126 /root/php-5.4.35/Zend/zend_list.c: No such file or directory. (gdb) bt #0 0x000000000068bd4c in zend_fetch_resource (passed_id=passed_id@entry=0x7fffffffa228, default_id=default_id@entry=-1, resource_type_name=resource_type_name@entry=0x7ffff6092cb1 "Libvirt virtual network", found_resource_type=found_resource_type@entry=0x0, num_resource_types=num_resource_types@entry=1) at /root/php-5.4.35/Zend/zend_list.c:126 #1 0x00007ffff60889ea in zif_libvirt_network_set_active (ht=2, return_value=0x7ffff7fbf068, return_value_ptr=<optimized out>, this_ptr=<optimized out>, return_value_used=<optimized out>) at libvirt-php.c:7569 #2 0x0000000000720f78 in zend_do_fcall_common_helper_SPEC (execute_data=0x7ffff7f87060) at /root/php-5.4.35/Zend/zend_vm_execute.h:643 #3 0x00000000006a285c in execute (op_array=0x7ffff7fbe5f0) at /root/php-5.4.35/Zend/zend_vm_execute.h:410 #4 0x000000000067dffe in zend_execute_scripts (type=type@entry=8, retval=retval@entry=0x0, file_count=file_count@entry=3) at /root/php-5.4.35/Zend/zend.c:1329 #5 0x0000000000621349 in php_execute_script (primary_file=primary_file@entry=0x7fffffffc6d0) at /root/php-5.4.35/main/main.c:2502 #6 0x0000000000722df4 in do_cli (argc=4, argv=0x7fffffffdaa8) at /root/php-5.4.35/sapi/cli/php_cli.c:989 #7 0x00000000004298b8 in main (argc=4, argv=0x7fffffffdaa8) at /root/php-5.4.35/sapi/cli/php_cli.c:1365 ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=68484&edit=1

« previous php.bugs (#188754) next »