Bug #72526 [Com]: segfault in curl_setopt()

From: Date: Wed, 27 Jul 2016 12:26:05 +0000
Subject: Bug #72526 [Com]: segfault in curl_setopt()
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-202635@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=72526&edit=1 ID: 72526 Comment by: arie dot mail at gmail dot com Reported by: lazy at iq dot pl Summary: segfault in curl_setopt() Status: Open Type: Bug Package: cURL related Operating System: Debian Wheezy PHP Version: 7.0.8 Block user comment: N Private report: N New Comment: I've also have this issue, could reproduce from the same little test script. Curl version: 7.50.0 PHP Version 7.0.9 gcc (Debian 4.7.2-5) 4.7.2 Debian: 7.11 bt: (gdb) bt #0 i_zval_ptr_dtor (zval_ptr=0x4) at /usr/local/directadmin/custombuild/php-7.0.9/Zend/zend_variables.h:56 #1 _zval_ptr_dtor (zval_ptr=0x4) at /usr/local/directadmin/custombuild/php-7.0.9/Zend/zend_execute_API.c:533 #2 0x0000000000533de5 in _php_curl_setopt (ch=0x7f5583264780, option=<optimized out>, zvalue=0x7f5583214150) at /usr/local/directadmin/custombuild/php-7.0.9/ext/curl/interface.c:2822 #3 0x0000000000534dc4 in zif_curl_setopt (execute_data=<optimized out>, return_value=0x7f55832140c0) at /usr/local/directadmin/custombuild/php-7.0.9/ext/curl/interface.c:2984 #4 0x0000000000855372 in ZEND_DO_ICALL_SPEC_HANDLER (execute_data=0x7f5583214030) at /usr/local/directadmin/custombuild/php-7.0.9/Zend/zend_vm_execute.h:586 #5 0x0000000000845e60 in execute_ex (ex=<optimized out>) at /usr/local/directadmin/custombuild/php-7.0.9/Zend/zend_vm_execute.h:417 #6 0x0000000000896807 in zend_execute (op_array=op_array@entry=0x7f5583275000, return_value=return_value@entry=0x0) at /usr/local/directadmin/custombuild/php-7.0.9/Zend/zend_vm_execute.h:458 #7 0x00000000008080a4 in zend_execute_scripts (type=type@entry=8, retval=retval@entry=0x0, file_count=file_count@entry=3) at /usr/local/directadmin/custombuild/php-7.0.9/Zend/zend.c:1427 #8 0x00000000007a9a30 in php_execute_script (primary_file=primary_file@entry=0x7ffca1293e40) at /usr/local/directadmin/custombuild/php-7.0.9/main/main.c:2494 #9 0x000000000045378e in main (argc=<optimized out>, argv=<optimized out>) at /usr/local/directadmin/custombuild/php-7.0.9/sapi/fpm/fpm/fpm_main.c:1968 Previous Comments: ------------------------------------------------------------------------ [2016-07-01 11:37:04] lazy at iq dot pl this should be 4.5.0 not 4.0.5 ------------------------------------------------------------------------ [2016-07-01 11:16:13] lazy at iq dot pl ZEND_ASSUME(0) also segfaults on gcc version 4.9.2 (Debian 4.9.2-10) - debian 8 gcc version 4.8.5 20150623 (Red Hat 4.8.5-4) (GCC) - centos 7 any chance You ware using gcc older then 4.0.5 ? ------------------------------------------------------------------------ [2016-07-01 11:03:06] lazy at iq dot pl with some experiments I have narrowed it to calling zend_hash_index_update_ptr(ch->to_free->slist, option, slist); with NULL slist, Breakpoint 2, _zend_hash_index_update (ht=0x3b3e8257268, h=h@entry=10023, pData=pData@entry=0x3eb430303e0) at /usr/src/new/apache2-suexec/work/pri/php-src/Zend/zend_hash.c:838 838 return _zend_hash_index_add_or_update_i(ht, h, pData, HASH_UPDATE ZEND_FILE_LINE_RELAY_CC); (gdb) bt #0 _zend_hash_index_update (ht=0x3b3e8257268, h=h@entry=10023, pData=pData@entry=0x3eb430303e0) at /usr/src/new/apache2-suexec/work/pri/php-src/Zend/zend_hash.c:838 #1 0x000000000054848e in zend_hash_index_update_ptr (pData=0x0, h=10023, ht=<optimized out>) at /usr/src/new/apache2-suexec/work/pri/php-src/Zend/zend_hash.h:642 #2 _php_curl_setopt (ch=0x3b3e825e780, option=10023, zvalue=0x3b3e8214130) at /usr/src/new/apache2-suexec/work/pri/php-src/ext/curl/interface.c:2680 #3 0x0000000000549224 in zif_curl_setopt (execute_data=<optimized out>, return_value=0x3eb43030470) at /usr/src/new/apache2-suexec/work/pri/php-src/ext/curl/interface.c:3001 #4 0x00000000007472c7 in ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_HANDLER (execute_data=0x3b3e8214030) at /usr/src/new/apache2-suexec/work/pri/php-src/Zend/zend_vm_execute.h:632 #5 0x0000000000736a18 in execute_ex (ex=<optimized out>) at /usr/src/new/apache2-suexec/work/pri/php-src/Zend/zend_vm_execute.h:432 #6 0x000000000078ee30 in zend_execute (op_array=op_array@entry=0x3b3e827f000, return_value=return_value@entry=0x0) at /usr/src/new/apache2-suexec/work/pri/php-src/Zend/zend_vm_execute.h:474 #7 0x00000000006ef314 in zend_execute_scripts (type=type@entry=8, retval=retval@entry=0x0, file_count=file_count@entry=3) at /usr/src/new/apache2-suexec/work/pri/php-src/Zend/zend.c:1441 #8 0x000000000068f0a0 in php_execute_script (primary_file=primary_file@entry=0x3eb43032980) at /usr/src/new/apache2-suexec/work/pri/php-src/main/main.c:2532 #9 0x0000000000791000 in do_cli (argc=2, argv=0x408b690) at /usr/src/new/apache2-suexec/work/pri/php-src/sapi/cli/php_cli.c:990 #10 0x000000000043290c in main (argc=2, argv=0x408b690) at /usr/src/new/apache2-suexec/work/pri/php-src/sapi/cli/php_cli.c:1378 (gdb) cont Breakpoint 2, _zend_hash_index_update (ht=0x4, h=h@entry=10023, pData=pData@entry=0x3eb430303e0) at /usr/src/new/apache2-suexec/work/pri/php-src/Zend/zend_hash.c:838 838 return _zend_hash_index_add_or_update_i(ht, h, pData, HASH_UPDATE ZEND_FILE_LINE_RELAY_CC); (gdb) bt #0 _zend_hash_index_update (ht=0x4, h=h@entry=10023, pData=pData@entry=0x3eb430303e0) at /usr/src/new/apache2-suexec/work/pri/php-src/Zend/zend_hash.c:838 #1 0x000000000054848e in zend_hash_index_update_ptr (pData=0x0, h=10023, ht=<optimized out>) at /usr/src/new/apache2-suexec/work/pri/php-src/Zend/zend_hash.h:642 #2 _php_curl_setopt (ch=0x3b3e825e780, option=10023, zvalue=0x3b3e8214130) at /usr/src/new/apache2-suexec/work/pri/php-src/ext/curl/interface.c:2680 #3 0x0000000000549224 in zif_curl_setopt (execute_data=<optimized out>, return_value=0x3eb43030470) at /usr/src/new/apache2-suexec/work/pri/php-src/ext/curl/interface.c:3001 #4 0x00000000007472c7 in ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_HANDLER (execute_data=0x3b3e8214030) at /usr/src/new/apache2-suexec/work/pri/php-src/Zend/zend_vm_execute.h:632 #5 0x0000000000736a18 in execute_ex (ex=<optimized out>) at /usr/src/new/apache2-suexec/work/pri/php-src/Zend/zend_vm_execute.h:432 #6 0x000000000078ee30 in zend_execute (op_array=op_array@entry=0x3b3e827f000, return_value=return_value@entry=0x0) at /usr/src/new/apache2-suexec/work/pri/php-src/Zend/zend_vm_execute.h:474 #7 0x00000000006ef314 in zend_execute_scripts (type=type@entry=8, retval=retval@entry=0x0, file_count=file_count@entry=3) at /usr/src/new/apache2-suexec/work/pri/php-src/Zend/zend.c:1441 #8 0x000000000068f0a0 in php_execute_script (primary_file=primary_file@entry=0x3eb43032980) at /usr/src/new/apache2-suexec/work/pri/php-src/main/main.c:2532 #9 0x0000000000791000 in do_cli (argc=2, argv=0x408b690) at /usr/src/new/apache2-suexec/work/pri/php-src/sapi/cli/php_cli.c:990 #10 0x000000000043290c in main (argc=2, argv=0x408b690) at /usr/src/new/apache2-suexec/work/pri/php-src/sapi/cli/php_cli.c:1378 zend_hash_index_update_ptr() is called twice maybe because of some curruption in Zend/zend_hash.h:644 ZEND_ASSUME(Z_PTR_P(zv)); removing Zend/zend_hash.h:644 ZEND_ASSUME(Z_PTR_P(zv)); "fixes" the problem ZEND_ASSUME is defined as #elif ((defined(__GNUC__) && ZEND_GCC_VERSION >= 4005) || __has_builtin(__builtin_unreachable)) && PHP_HAVE_BUILTIN_EXPECT # define ZEND_ASSUME(c) do { \ if (__builtin_expect(!(c), 0)) __builtin_unreachable(); \ } while (0) https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html — Built-in Function: long __builtin_expect (long exp, long c) You may use __builtin_expect to provide the compiler with branch prediction information. In general, you should prefer to use actual profile feedback for this (-fprofile-arcs), as programmers are notoriously bad at predicting how their programs actually perform. However, there are applications in which this data is hard to collect. c is NULL so !(c) is 1 and __builtin_unreachable is called which leads to segfault maybe becaouse of some gcc problems with __builtin_unreachable() on debian's gcc (-O0 works fine) can we fix this by adding if(zend_hash_num_elements(ph) == 0) { php_error_docref(NULL, E_WARNING, "You must pass an non empty argument"); return 1; } before calling zend_hash_index_update_ptr() ? on debian's gcc int main() { int *c=0; do { \ if (__builtin_expect(!(c), 0)) __builtin_unreachable(); \ } while (0); } with -O2 is also segfaulting, -O0 is ok what's the semantic of ZEND_ASSUME should it bail on an NULL argument ? ------------------------------------------------------------------------ [2016-06-30 15:55:20] laruence@php.net I can not reproduce this on ubuntu ------------------------------------------------------------------------ [2016-06-30 13:48:01] lazy at iq dot pl Description: ------------ gcc version 4.7.2 (Debian 4.7.2-5) compiling with O0 "fixes" the problem, also works fine on centos 7, so it might be some optimization issue Breakpoint 1, _php_curl_setopt (ch=0x3d61925b780, option=10023, zvalue=0x3d619213160) at /usr/src/new/apache2-suexec/work/pri/php-7.0.8/ext/curl/interface.c:2133 2133 { (gdb) p zvalue $1 = (zval *) 0x3d619213160 (gdb) list 2128 dupch->res = Z_RES_P(return_value); 2129 } 2130 /* }}} */ 2131 2132 static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue) /* {{{ */ 2133 { 2134 CURLcode error = CURLE_OK; 2135 zend_long lval; 2136 2137 ZVAL_DEREF(zvalue); (gdb) next 2137 ZVAL_DEREF(zvalue); (gdb) 2133 { (gdb) 2137 ZVAL_DEREF(zvalue); (gdb) 2138 switch (option) { (gdb) 3626 } (gdb) 2603 ph = HASH_OF(zvalue); (gdb) next 2604 if (!ph) { (gdb) 2650 ZEND_HASH_FOREACH_VAL(ph, current) { (gdb) 2661 if ((*ch->clone) == 1) { (gdb) 2662 zend_hash_index_update_ptr(ch->to_free->slist, option, slist); (gdb) 2661 if ((*ch->clone) == 1) { (gdb) 2662 zend_hash_index_update_ptr(ch->to_free->slist, option, slist); (gdb) 2822 zval_ptr_dtor(&ch->handlers->progress->func_name); (gdb) Program received signal SIGSEGV, Segmentation fault. _zval_ptr_dtor (zval_ptr=0x4) at /usr/src/new/apache2-suexec/work/pri/php-7.0.8/Zend/zend_execute_API.c:533 533 i_zval_ptr_dtor(zval_ptr ZEND_FILE_LINE_RELAY_CC); gdb) bt #0 _zval_ptr_dtor (zval_ptr=0x4) at /usr/src/new/apache2-suexec/work/pri/php-7.0.8/Zend/zend_execute_API.c:533 #1 0x00000000005807e5 in _php_curl_setopt (ch=ch@entry=0x2c7a8fe3700, option=<optimized out>, zvalue=zvalue@entry=0x2c7a8fe3520) at /usr/src/new/apache2-suexec/work/pri/php-7.0.8/ext/curl/interface.c:2822 #2 0x00000000005814b5 in zif_curl_setopt_array (execute_data=<optimized out>, return_value=0x2c7a9c16660) at /usr/src/new/apache2-suexec/work/pri/php-7.0.8/ext/curl/interface.c:3015 #3 0x00000000008f8fed in ZEND_DO_FCALL_SPEC_HANDLER (execute_data=0x2c7a9c16430) at /usr/src/new/apache2-suexec/work/pri/php-7.0.8/Zend/zend_vm_execute.h:842 #4 0x00000000008b66a0 in execute_ex (ex=<optimized out>) at /usr/src/new/apache2-suexec/work/pri/php-7.0.8/Zend/zend_vm_execute.h:417 #5 0x0000000000907097 in zend_execute (op_array=op_array@entry=0x2c7a9c78000, return_value=return_value@entry=0x0) at /usr/src/new/apache2-suexec/work/pri/php-7.0.8/Zend/zend_vm_execute.h:458 #6 0x0000000000878a24 in zend_execute_scripts (type=type@entry=8, retval=retval@entry=0x0, file_count=file_count@entry=3) at /usr/src/new/apache2-suexec/work/pri/php-7.0.8/Zend/zend.c:1427 #7 0x000000000081aaa0 in php_execute_script (primary_file=primary_file@entry=0x3dcd7e2eaa0) at /usr/src/new/apache2-suexec/work/pri/php-7.0.8/main/main.c:2494 #8 0x00000000004566ca in main (argc=1, argv=0x3dcd7e2ee58) at /usr/src/new/apache2-suexec/work/pri/php-7.0.8/sapi/cgi/cgi_main.c:2453 Please look at https://github.com/php/php-src/blob/master/ext/curl/interface.c#L2663-L2672 May it be running ZEND_HASH_FOREACH_VAL() loop on an empty hash corrupting the stack ? Test script: --------------- $ch=curl_init(); curl_setopt($ch, CURLOPT_HTTPHEADER, array()); Expected result: ---------------- Normal execution Actual result: -------------- Segfault: gdb) bt #0 _zval_ptr_dtor (zval_ptr=0x4) at /usr/src/new/apache2-suexec/work/pri/php-7.0.8/Zend/zend_execute_API.c:533 #1 0x00000000005807e5 in _php_curl_setopt (ch=ch@entry=0x2c7a8fe3700, option=<optimized out>, zvalue=zvalue@entry=0x2c7a8fe3520) at /usr/src/new/apache2-suexec/work/pri/php-7.0.8/ext/curl/interface.c:2822 #2 0x00000000005814b5 in zif_curl_setopt_array (execute_data=<optimized out>, return_value=0x2c7a9c16660) at /usr/src/new/apache2-suexec/work/pri/php-7.0.8/ext/curl/interface.c:3015 #3 0x00000000008f8fed in ZEND_DO_FCALL_SPEC_HANDLER (execute_data=0x2c7a9c16430) at /usr/src/new/apache2-suexec/work/pri/php-7.0.8/Zend/zend_vm_execute.h:842 #4 0x00000000008b66a0 in execute_ex (ex=<optimized out>) at /usr/src/new/apache2-suexec/work/pri/php-7.0.8/Zend/zend_vm_execute.h:417 #5 0x0000000000907097 in zend_execute (op_array=op_array@entry=0x2c7a9c78000, return_value=return_value@entry=0x0) at /usr/src/new/apache2-suexec/work/pri/php-7.0.8/Zend/zend_vm_execute.h:458 #6 0x0000000000878a24 in zend_execute_scripts (type=type@entry=8, retval=retval@entry=0x0, file_count=file_count@entry=3) at /usr/src/new/apache2-suexec/work/pri/php-7.0.8/Zend/zend.c:1427 #7 0x000000000081aaa0 in php_execute_script (primary_file=primary_file@entry=0x3dcd7e2eaa0) at /usr/src/new/apache2-suexec/work/pri/php-7.0.8/main/main.c:2494 #8 0x00000000004566ca in main (argc=1, argv=0x3dcd7e2ee58) at /usr/src/new/apache2-suexec/work/pri/php-7.0.8/sapi/cgi/cgi_main.c:2453 ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=72526&edit=1

« previous php.bugs (#202635) next »