Bug #61046 [Fbk]: Segfault when memory limit is hit while copying hash table

From: Date: Thu, 20 Dec 2012 15:28:22 +0000
Subject: Bug #61046 [Fbk]: Segfault when memory limit is hit while copying hash table
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-175493@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=61046&edit=1

 ID:                 61046
 Updated by:         laruence@php.net
 Reported by:        nikic@php.net
 Summary:            Segfault when memory limit is hit while copying hash
                     table
 Status:             Feedback
 Type:               Bug
 Package:            Reproducible crash
 PHP Version:        5.4.0RC7
 Block user comment: N
 Private report:     N

 New Comment:

another way to fix this is promote the ht point assignment in ctor(list blow), 
but there is still a chance that alloc failed when try to alloc memory for ht.

so I still think the fix I attached is the better one.

diff --git a/Zend/zend_variables.c b/Zend/zend_variables.c
index 25a66a1..bb6927a 100644
--- a/Zend/zend_variables.c
+++ b/Zend/zend_variables.c
@@ -134,9 +134,9 @@ ZEND_API void _zval_copy_ctor_func(zval *zvalue 
ZEND_FILE_LINE_DC)
 					return; /* do nothing */
 				}
 				ALLOC_HASHTABLE_REL(tmp_ht);
+				zvalue->value.ht = tmp_ht;
 				zend_hash_init(tmp_ht, 
zend_hash_num_elements(original_ht), NULL, ZVAL_PTR_DTOR, 0);
 				zend_hash_copy(tmp_ht, original_ht, 
(copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
-				zvalue->value.ht = tmp_ht;
 			}
 			break;
 		case IS_OBJECT:


Previous Comments:
------------------------------------------------------------------------
[2012-12-20 15:08:30] laruence@php.net

quick fix attached, could you please verify it?

------------------------------------------------------------------------
[2012-12-20 15:07:27] laruence@php.net

The following patch has been added/updated:

Patch Name: bug61046.patch
Revision:   1356016047
URL:        https://bugs.php.net/patch-display.php?bug=61046&patch=bug61046.patch&revision=1356016047

------------------------------------------------------------------------
[2012-12-20 11:18:02] arrtedone at gmail dot com

Description:
------------
Same here, reproducable, but with memory limit set to 128M (note that i am not using the provided
test script, it crached randomly)

Test script:
-------------
-

System information :
OS : Fedora 17 Linux nask0 3.6.10-2.fc17.x86_64 #1 SMP Tue Dec 11 18:07:34 UTC 2012 x86_64
PHP version 5.4.9 :
PHP API : 20100412
PHP Extension : 20100525
Zend Extension : 220100525
Zend Extension Build : API220100525,NTS
PHP Extension Build : API20100525,NTS
Thread Safety: disabled
Zend Signal Handling: disabled
Zend Memory Manager: enabled 
Apache Version: Apache/2.2.22 (Fedora) DAV/2 PHP/5.4.9
Apache API Version : 20051115 


GDB backtrace : 
---------------
Program received signal SIGSEGV, Segmentation fault.
zend_mm_remove_from_free_list (heap=0x7f75283c10d0, mm_block=0x7f752a24b3f8) at
/usr/src/debug/php-5.4.9/Zend/zend_alloc.c:833
833			if (UNEXPECTED(prev->next_free_block != mm_block) || UNEXPECTED(next->prev_free_block !=
mm_block)) {
(gdb) continue 
Continuing.

Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.

------------------------------------------------------------------------
[2012-02-10 18:08:37] rasmus@php.net

Same here. Reproducable on 64-bit Linux with memory_limit set to "512k".

The segfault is here:

zend_mm_remove_from_free_list (heap=0xf71730, mm_block=0x7ffff7fae1c8) at 
/home/rasmus/php-src/branches/PHP_5_4/Zend/zend_alloc.c:805
805				ZEND_MM_CHECK_TREE(mm_block);

(gdb) p *mm_block
$2 = {info = {_size = 16400, _prev = 57}, prev_free_block = 0x7ffff7fae1c8, 
next_free_block = 0x7ffff7fae1c8, parent = 0x0, child = {0x0, 0x0}}

Note that parent is NULL there and ZEND_MM_CHECK_TREE tries to dereference 
*parent

------------------------------------------------------------------------
[2012-02-10 17:46:09] jpauli@php.net

Notice that I only reproduce with memory_limit set to accurate 512k , not 500k as 
in bug text, nor even 511k

------------------------------------------------------------------------


The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at

    https://bugs.php.net/bug.php?id=61046


-- 
Edit this bug report at https://bugs.php.net/bug.php?id=61046&edit=1


Thread (13 messages)

« previous php.bugs (#175493) next »