[php-src] Issue #11189: Exceeding memory limit in zend_hash_do_resize leaves the array in an invalid state

From: Date: Fri, 05 May 2023 09:57:42 +0000
Subject: [php-src] Issue #11189: Exceeding memory limit in zend_hash_do_resize leaves the array in an invalid state
Groups: php.bugs 
Request: Send a blank email to php-bugs+get-244373@lists.php.net to get a copy of this message
Issue: https://github.com/php/php-src/issues/11189 Author: bwoebi ### Description Cross-posting a report we got on our extension: https://github.com/DataDog/dd-trace-php/issues/2030#issuecomment-1535130277 ``` php -dmemory_limit=10M -r 'ob_start(function() { global $a; for ($i = count($a); $i > 0; --$i) { $a[] = 2; } }); $a = []; while (1) { $a[] = 1; }' ``` Getting a memory limit exceeded error in zend_hash_do_resize crashes when the array is manipulated afterwards, with a following backtrace: ``` #0 _zend_hash_index_add_or_update_i (flag=18, pData=0xfffff4690150, h=262399, ht=0xfffff4655230) at /usr/local/src/php/Zend/zend_hash.c:1051 #1 zend_hash_next_index_insert (ht=ht@entry=0xfffff4655230, pData=0xfffff4690150) at /usr/local/src/php/Zend/zend_hash.c:1142 #2 0x0000aaaaaaf7c8bc in ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_CONST_HANDLER () at /usr/local/src/php/Zend/zend_vm_execute.h:47376 #3 0x0000aaaaaaf98558 in execute_ex (ex=0xfffff3c00ff8) at /usr/local/src/php/Zend/zend_vm_execute.h:59995 #4 0x0000aaaaaaf17464 in zend_call_function (fci_cache=0xfffff4654120, fci=0xfffff46540e0) at /usr/local/src/php/Zend/zend_execute_API.c:930 #5 zend_call_function (fci=0xfffff46540e0, fci_cache=<optimized out>) at /usr/local/src/php/Zend/zend_execute_API.c:732 #6 0x0000aaaaaaf2f964 in zend_fcall_info_call (fci=0xfffff46540e0, fcc=0xfffff4654120, retval_ptr=retval_ptr@entry=0xffffffffd218, args=args@entry=0x0) at /usr/local/src/php/Zend/zend_API.c:4137 #7 0x0000aaaaaaed60f4 in php_output_handler_op (context=0xffffffffd248, handler=0xfffff466f050) at /usr/local/src/php/main/output.c:970 #8 php_output_stack_pop (flags=flags@entry=17) at /usr/local/src/php/main/output.c:1231 #9 0x0000aaaaaaed6598 in php_output_discard_all () at /usr/local/src/php/main/output.c:365 #10 0x0000aaaaaabde368 in php_error_cb (orig_type=1, error_filename=0xfffff465b360, error_lineno=1, message=0xfffff4654150) at /usr/local/src/php/main/main.c:1274 #11 0x0000aaaaaabdfbe8 in zend_error_zstr_at (orig_type=orig_type@entry=1, error_filename=error_filename@entry=0xfffff465b360, error_lineno=error_lineno@entry=1, message=message@entry=0xfffff4654150) at /usr/local/src/php/Zend/zend.c:1390 #12 0x0000aaaaaabdff48 in zend_error_va_list (orig_type=1, error_filename=0xfffff465b360, error_lineno=1, format=<optimized out>, args=<error reading variable: Cannot access memory at address 0x80000>) at /usr/local/src/php/Zend/zend.c:1483 #13 0x0000aaaaaabe02a0 in zend_error_noreturn (type=type@entry=1, format=format@entry=0xaaaaab87f740 "Allowed memory size of %zu bytes exhausted (tried to allocate %zu bytes)") at /usr/local/src/php/Zend/zend.c:1590 #14 0x0000aaaaaabdf594 in zend_mm_safe_error (format=format@entry=0xaaaaab87f740 "Allowed memory size of %zu bytes exhausted (tried to allocate %zu bytes)", limit=10485760, size=size@entry=8388616, heap=<optimized out>) at /usr/local/src/php/Zend/zend_alloc.c:383 #15 0x0000aaaaaaefb094 in zend_mm_realloc_huge (heap=0xfffff4600040, ptr=0xfffff3800000, size=8388616, copy_size=4194312) at /usr/local/src/php/Zend/zend_alloc.c:1542 #16 0x0000aaaaaaf327b8 in zend_hash_packed_grow (ht=0xfffff4655230) at /usr/local/src/php/Zend/zend_types.h:648 #17 0x0000aaaaaaf35490 in _zend_hash_index_add_or_update_i (flag=18, pData=0xfffff4693160, h=262144, ht=0xfffff4655230) at /usr/local/src/php/Zend/zend_hash.c:1057 #18 zend_hash_next_index_insert (ht=ht@entry=0xfffff4655230, pData=0xfffff4693160) at /usr/local/src/php/Zend/zend_hash.c:1142 #19 0x0000aaaaaaf7c8bc in ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_CONST_HANDLER () at /usr/local/src/php/Zend/zend_vm_execute.h:47376 #20 0x0000aaaaaaf98558 in execute_ex (ex=0xfffff3c00ff8) at /usr/local/src/php/Zend/zend_vm_execute.h:59995 #21 0x0000aaaaaafa2648 in zend_execute (op_array=0xfffff467d100, return_value=0xffffffffd968) at /usr/local/src/php/Zend/zend_vm_execute.h:60380 #22 0x0000aaaaaaf16aa8 in zend_eval_stringl (str=<optimized out>, str_len=<optimized out>, retval_ptr=0x0, string_name=<optimized out>) at /usr/local/src/php/Zend/zend_execute_API.c:1279 #23 0x0000aaaaaaf16c44 in zend_eval_stringl_ex (str=<optimized out>, str_len=<optimized out>, retval_ptr=<optimized out>, string_name=<optimized out>, handle_exceptions=true) at /usr/local/src/php/Zend/zend_execute_API.c:1321 #24 0x0000aaaaab0102f4 in do_cli (argc=4, argv=0xaaaaaba52870) at /usr/local/src/php/sapi/cli/php_cli.c:995 #25 0x0000aaaaaabf76f8 in main (argc=4, argv=<optimized out>) at /usr/local/src/php/sapi/cli/php_cli.c:1333 ``` This happens due to the order of operations being the wrong way round in zend_hash_do_resize: https://github.com/php/php-src/blob/a65cdd97a148dccdb68a5f58c258d54c305f1b2e/Zend/zend_hash.c#L1250-L1251 It's setting the nTableSize before attempting to do the allocation, leaving the array in an unstable state. ### PHP Version PHP 8.1+ ### Operating System _No response_

« previous php.bugs (#244373) next »