From 776e73785320112eeb47c62e06823bb1aa464c90 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Sun, 5 Nov 2023 01:27:22 +0100 Subject: [PATCH 1/2] Fix unspecified behaviour in zend_alloc in heap->limit computation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Right-shifting a negative number is unspecified (i.e. implementation-defined) behaviour [1]. If we take a look at the generated assembly [2], we see that the wrong value is computed. Fix it by using Z_UL instead of Z_L. While we're at it, just change every occurrence of this pattern to use Z_UL instead of casting. [1] https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1548.pdf ยง6.5.7.5 [2] https://godbolt.org/z/4Y1qKKjsh --- Zend/zend_alloc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c index 7fd41f3b1ab96..08d72cc343579 100644 --- a/Zend/zend_alloc.c +++ b/Zend/zend_alloc.c @@ -1914,7 +1914,7 @@ static zend_mm_heap *zend_mm_init(void) heap->peak = 0; #endif #if ZEND_MM_LIMIT - heap->limit = ((size_t)Z_L(-1) >> (size_t)Z_L(1)); + heap->limit = Z_UL(-1) >> Z_UL(1); heap->overflow = 0; #endif #if ZEND_MM_CUSTOM @@ -2859,7 +2859,7 @@ static void alloc_globals_ctor(zend_alloc_globals *alloc_globals) zend_mm_heap *mm_heap = alloc_globals->mm_heap = malloc(sizeof(zend_mm_heap)); memset(mm_heap, 0, sizeof(zend_mm_heap)); mm_heap->use_custom_heap = ZEND_MM_CUSTOM_HEAP_STD; - mm_heap->limit = ((size_t)Z_L(-1) >> (size_t)Z_L(1)); + mm_heap->limit = Z_UL(-1) >> Z_UL(1); mm_heap->overflow = 0; if (!tracked) { @@ -3048,7 +3048,7 @@ ZEND_API zend_mm_heap *zend_mm_startup_ex(const zend_mm_handlers *handlers, void heap->peak = 0; #endif #if ZEND_MM_LIMIT - heap->limit = (Z_L(-1) >> Z_L(1)); + heap->limit = Z_UL(-1) >> Z_UL(1); heap->overflow = 0; #endif #if ZEND_MM_CUSTOM From e53d8e1808f98d81708ffba524fa89492a7b8dc1 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Mon, 6 Nov 2023 19:06:51 +0100 Subject: [PATCH 2/2] Fix 32-bit --- Zend/zend_alloc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c index 08d72cc343579..c41f6118607e2 100644 --- a/Zend/zend_alloc.c +++ b/Zend/zend_alloc.c @@ -1914,7 +1914,7 @@ static zend_mm_heap *zend_mm_init(void) heap->peak = 0; #endif #if ZEND_MM_LIMIT - heap->limit = Z_UL(-1) >> Z_UL(1); + heap->limit = (size_t)Z_L(-1) >> 1; heap->overflow = 0; #endif #if ZEND_MM_CUSTOM @@ -2859,7 +2859,7 @@ static void alloc_globals_ctor(zend_alloc_globals *alloc_globals) zend_mm_heap *mm_heap = alloc_globals->mm_heap = malloc(sizeof(zend_mm_heap)); memset(mm_heap, 0, sizeof(zend_mm_heap)); mm_heap->use_custom_heap = ZEND_MM_CUSTOM_HEAP_STD; - mm_heap->limit = Z_UL(-1) >> Z_UL(1); + mm_heap->limit = (size_t)Z_L(-1) >> 1; mm_heap->overflow = 0; if (!tracked) { @@ -3048,7 +3048,7 @@ ZEND_API zend_mm_heap *zend_mm_startup_ex(const zend_mm_handlers *handlers, void heap->peak = 0; #endif #if ZEND_MM_LIMIT - heap->limit = Z_UL(-1) >> Z_UL(1); + heap->limit = (size_t)Z_L(-1) >> 1; heap->overflow = 0; #endif #if ZEND_MM_CUSTOM