com php-src: Fixed bug #70258 and #70253: NEWS Zend/tests/bug70253.phpt Zend/tests/bug70258.phpt Zend/zend_hash.c Zend/zend_typ es.h

From: Date: Thu, 13 Aug 2015 04:08:57 +0000
Subject: com php-src: Fixed bug #70258 and #70253: NEWS Zend/tests/bug70253.phpt Zend/tests/bug70258.phpt Zend/zend_hash.c Zend/zend_typ es.h
Groups: php.cvs 
Request: Send a blank email to php-cvs+get-88502@lists.php.net to get a copy of this message
Commit: a089ce0cc6e0bade9bf94399a13bbd63448874b0 Author: Xinchen Hui <laruence@php.net> Thu, 13 Aug 2015 12:08:57 +0800 Parents: e17b1266dbcc55942fdfa6e62318104c2fa0f3be Branches: master Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=a089ce0cc6e0bade9bf94399a13bbd63448874b0 Log: Fixed bug #70258 and #70253 Bugs: https://bugs.php.net/70258 https://bugs.php.net/70253 Changed paths: M NEWS A Zend/tests/bug70253.phpt A Zend/tests/bug70258.phpt M Zend/zend_hash.c M Zend/zend_types.h Diff: diff --git a/NEWS b/NEWS index aaf2417..3741df9 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,9 @@ PHP NEWS 20 Aug 2015, PHP 7.0.0 RC 1 - Core: + . Fixed bug #70258 (Segfault if do_resize fails to allocated memory). + (Laruence) + . Fixed bug #70253 (segfault at _efree () in zend_alloc..c:1389). (Laruence) . Fixed bug #70240 (Segfault when doing unset($var());). (Laruence) . Fixed bug #70223 (Incrementing value returned by magic getter). (Laruence) . Fixed bug #70215 (Segfault when __invoke is static). (Bob) diff --git a/Zend/tests/bug70253.phpt b/Zend/tests/bug70253.phpt new file mode 100644 index 0000000..dd760df --- /dev/null +++ b/Zend/tests/bug70253.phpt @@ -0,0 +1,17 @@ +--TEST-- +Bug #70253 (segfault at _efree () in zend_alloc.c:1389) +--INI-- +memory_limit=2M +--SKIPIF-- +<?php +$zend_mm_enabled = getenv("USE_ZEND_ALLOC"); +if ($zend_mm_enabled === "0") { + die("skip Zend MM disabled"); +} +?> +--FILE-- +<?php +unserialize('a:2:{i:0;O:9:"000000000":10000000'); +?> +--EXPECTF-- +Fatal error: Allowed memory size of 2097152 bytes exhausted%s(tried to allocate %d bytes) in %s on line %d diff --git a/Zend/tests/bug70258.phpt b/Zend/tests/bug70258.phpt new file mode 100644 index 0000000..5ffd7bf --- /dev/null +++ b/Zend/tests/bug70258.phpt @@ -0,0 +1,28 @@ +--TEST-- +Bug #70258 (Segfault if do_resize fails to allocated memory) +--INI-- +memory_limit=2M +--SKIPIF-- +<?php +$zend_mm_enabled = getenv("USE_ZEND_ALLOC"); +if ($zend_mm_enabled === "0") { + die("skip Zend MM disabled"); +} +?> +--FILE-- +<?php +class A { + public $arr; + public function core() { + $this->arr["no_pack"] = 1; + while (1) { + $this->arr[] = 1; + } + } +} + +$a = new A; +$a->core(); +?> +--EXPECTF-- +Fatal error: Allowed memory size of 2097152 bytes exhausted%s(tried to allocate %d bytes) in %s on line %d diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c index 2347f99..7e06cf0 100644 --- a/Zend/zend_hash.c +++ b/Zend/zend_hash.c @@ -795,13 +795,15 @@ static void ZEND_FASTCALL zend_hash_do_resize(HashTable *ht) zend_hash_rehash(ht); HANDLE_UNBLOCK_INTERRUPTIONS(); } else if (ht->nTableSize < HT_MAX_SIZE) { /* Let's double the table size */ - void *old_data = HT_GET_DATA_ADDR(ht); + void *new_data, *old_data = HT_GET_DATA_ADDR(ht); + uint32_t nSize = ht->nTableSize + ht->nTableSize; Bucket *old_buckets = ht->arData; HANDLE_BLOCK_INTERRUPTIONS(); - ht->nTableSize += ht->nTableSize; + new_data = pemalloc(HT_DATA_SIZE_EX(nSize) + HT_HASH_SIZE_EX(-nSize), ht->u.flags & HASH_FLAG_PERSISTENT); + ht->nTableSize = nSize; ht->nTableMask = -ht->nTableSize; - HT_SET_DATA_ADDR(ht, pemalloc(HT_SIZE(ht), ht->u.flags & HASH_FLAG_PERSISTENT)); + HT_SET_DATA_ADDR(ht, new_data); memcpy(ht->arData, old_buckets, sizeof(Bucket) * ht->nNumUsed); pefree(old_data, ht->u.flags & HASH_FLAG_PERSISTENT); zend_hash_rehash(ht); @@ -812,20 +814,22 @@ static void ZEND_FASTCALL zend_hash_do_resize(HashTable *ht) } ZEND_API void ZEND_FASTCALL zend_hash_resize(HashTable *ht, uint32_t nSize) { - void *old_data = HT_GET_DATA_ADDR(ht); + nSize = zend_hash_check_size(nSize); if (ht->u.flags & HASH_FLAG_INITIALIZED) { + void *new_data, *old_data = HT_GET_DATA_ADDR(ht); Bucket *old_buckets = ht->arData; HANDLE_BLOCK_INTERRUPTIONS(); - ht->nTableSize = zend_hash_check_size(nSize); + new_data = pemalloc(HT_DATA_SIZE_EX(nSize) + HT_HASH_SIZE_EX(-nSize), ht->u.flags & HASH_FLAG_PERSISTENT); + ht->nTableSize = nSize; ht->nTableMask = -ht->nTableSize; - HT_SET_DATA_ADDR(ht, pemalloc(HT_SIZE(ht), ht->u.flags & HASH_FLAG_PERSISTENT)); + HT_SET_DATA_ADDR(ht, new_data); memcpy(ht->arData, old_buckets, sizeof(Bucket) * ht->nNumUsed); pefree(old_data, ht->u.flags & HASH_FLAG_PERSISTENT); zend_hash_rehash(ht); HANDLE_UNBLOCK_INTERRUPTIONS(); } else { - ht->nTableSize = zend_hash_check_size(nSize); + ht->nTableSize = nSize; } } diff --git a/Zend/zend_types.h b/Zend/zend_types.h index edcbe47..d4353f7 100644 --- a/Zend/zend_types.h +++ b/Zend/zend_types.h @@ -235,10 +235,14 @@ struct _zend_array { #define HT_HASH(ht, idx) \ HT_HASH_EX((ht)->arData, idx) +#define HT_HASH_SIZE_EX(nTableMask) \ + (((size_t)(uint32_t)-(int32_t)(nTableMask)) * sizeof(uint32_t)) +#define HT_DATA_SIZE_EX(nTableSize) \ + ((size_t)(nTableSize) * sizeof(Bucket)) #define HT_HASH_SIZE(ht) \ - (((size_t)(uint32_t)-(int32_t)(ht)->nTableMask) * sizeof(uint32_t)) + HT_HASH_SIZE_EX((ht)->nTableMask) #define HT_DATA_SIZE(ht) \ - ((size_t)(ht)->nTableSize * sizeof(Bucket)) + HT_DATA_SIZE_EX((ht)->nTableSize) #define HT_SIZE(ht) \ (HT_HASH_SIZE(ht) + HT_DATA_SIZE(ht)) #define HT_USED_SIZE(ht) \

« previous php.cvs (#88502) next »