Skip to content

Commit 0f0eab4

Browse files
committed
Fix #81070: Integer underflow when memory limit is exceeded
When the memory limit is reduced using an `ini_set("memory_limit", ..)` below the currently allocated memory. Further allocations should cause a memory limit exceeded error. This fixes the regression introduced in 7.2.23
1 parent 59522ba commit 0f0eab4

File tree

2 files changed

+15
-5
lines changed

2 files changed

+15
-5
lines changed

Zend/tests/bug81070.phpt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
--TEST--
2+
Bug #81070 Integer underflow in memory limit comparison
3+
--FILE--
4+
<?php
5+
$a = str_repeat("0", 5 * 1024 * 1024);
6+
ini_set("memory_limit", "3M");
7+
$b = str_repeat("0", 5 * 1024 * 1024);
8+
?>
9+
--EXPECTF--
10+
Fatal error: Allowed memory size of 3145728 bytes exhausted%s(tried to allocate %d bytes) in %s on line %d

Zend/zend_alloc.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -948,7 +948,7 @@ static void *zend_mm_alloc_pages(zend_mm_heap *heap, uint32_t pages_count ZEND_F
948948
heap->cached_chunks = chunk->next;
949949
} else {
950950
#if ZEND_MM_LIMIT
951-
if (UNEXPECTED(ZEND_MM_CHUNK_SIZE > heap->limit - heap->real_size)) {
951+
if (UNEXPECTED(heap->limit < heap->real_size || ZEND_MM_CHUNK_SIZE > heap->limit - heap->real_size)) {
952952
if (zend_mm_gc(heap)) {
953953
goto get_chunk;
954954
} else if (heap->overflow == 0) {
@@ -1474,8 +1474,8 @@ static zend_never_inline void *zend_mm_realloc_huge(zend_mm_heap *heap, void *pt
14741474
}
14751475
} else /* if (new_size > old_size) */ {
14761476
#if ZEND_MM_LIMIT
1477-
if (UNEXPECTED(new_size - old_size > heap->limit - heap->real_size)) {
1478-
if (zend_mm_gc(heap) && new_size - old_size <= heap->limit - heap->real_size) {
1477+
if (UNEXPECTED(heap->limit < heap->real_size || new_size - old_size > heap->limit - heap->real_size)) {
1478+
if (zend_mm_gc(heap) && heap->limit >= heap->real_size && new_size - old_size <= heap->limit - heap->real_size) {
14791479
/* pass */
14801480
} else if (heap->overflow == 0) {
14811481
#if ZEND_DEBUG
@@ -1766,8 +1766,8 @@ static void *zend_mm_alloc_huge(zend_mm_heap *heap, size_t size ZEND_FILE_LINE_D
17661766
}
17671767

17681768
#if ZEND_MM_LIMIT
1769-
if (UNEXPECTED(new_size > heap->limit - heap->real_size)) {
1770-
if (zend_mm_gc(heap) && new_size <= heap->limit - heap->real_size) {
1769+
if (UNEXPECTED(heap->limit < heap->real_size || new_size > heap->limit - heap->real_size)) {
1770+
if (zend_mm_gc(heap) && heap->limit >= heap->real_size && new_size <= heap->limit - heap->real_size) {
17711771
/* pass */
17721772
} else if (heap->overflow == 0) {
17731773
#if ZEND_DEBUG

0 commit comments

Comments
 (0)