From d1fceeec30a7fb1338c8513d3f8700757c80d10b Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Wed, 6 Aug 2025 17:40:53 +0200 Subject: [PATCH 1/2] Check stack limit in fuzzer executor The stack limit is checked when entering execute_ex(), but the fuzzer has its own execute function and does not call execute_ex(). Add a stack limit check in the fuzzer's execute function. Closes GH-19391 --- sapi/fuzzer/fuzzer-execute-common.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/sapi/fuzzer/fuzzer-execute-common.h b/sapi/fuzzer/fuzzer-execute-common.h index b3a77268b3926..20fcad111cd6b 100644 --- a/sapi/fuzzer/fuzzer-execute-common.h +++ b/sapi/fuzzer/fuzzer-execute-common.h @@ -53,7 +53,18 @@ static zend_always_inline void fuzzer_step(void) { static void (*orig_execute_ex)(zend_execute_data *execute_data); static void fuzzer_execute_ex(zend_execute_data *execute_data) { + +#ifdef ZEND_CHECK_STACK_LIMIT + if (UNEXPECTED(zend_call_stack_overflowed(EG(stack_limit)))) { + zend_call_stack_size_error(); + /* No opline was executed before exception */ + EG(opline_before_exception) = NULL; + /* Fall through to handle exception below. */ + } +#endif /* ZEND_CHECK_STACK_LIMIT */ + const zend_op *opline = EX(opline); + while (1) { fuzzer_step(); opline = ((opcode_handler_t) opline->handler)(execute_data, opline); From bd2766ce795df712923a818017fa2fa1169a7a23 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sat, 3 Feb 2024 14:54:23 +0000 Subject: [PATCH 2/2] zend call stack fixing stack limit for macOs arm64. 8MB sounded a prudent size for older 10.9 macOs release, however with newer mac with arm64, it triggers a stack overflow. Cherry picks b320aabc5e875ef101510eb39ea3b40e351dc6a5 (GH-13319) from PHP-8.4. Closes GH-19390. --- NEWS | 1 + Zend/tests/stack_limit/stack_limit_010.phpt | 5 ++++- Zend/zend_call_stack.c | 9 +++++++-- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index 727b25f0521f9..ad06a4eef1b7b 100644 --- a/NEWS +++ b/NEWS @@ -19,6 +19,7 @@ PHP NEWS a non-Generator delegate crashes). (Arnaud) . Fixed bug GH-18736 (Circumvented type check with return by ref + finally). (ilutov) + . Fixed zend call stack size for macOs/arm64. (David Carlier) - FTP: . Fix theoretical issues with hrtime() not being available. (nielsdos) diff --git a/Zend/tests/stack_limit/stack_limit_010.phpt b/Zend/tests/stack_limit/stack_limit_010.phpt index 312c2cf551696..9e37555e6decc 100644 --- a/Zend/tests/stack_limit/stack_limit_010.phpt +++ b/Zend/tests/stack_limit/stack_limit_010.phpt @@ -15,7 +15,10 @@ $stack = zend_test_zend_call_stack_get(); var_dump($stack); $expectedMaxSize = match(php_uname('s')) { - 'Darwin' => 8*1024*1024, + 'Darwin' => match(php_uname('m')) { + 'x86_64' => 8*1024*1024, + 'arm64' => 8372224, + }, 'FreeBSD' => match(php_uname('m')) { 'amd64' => 512*1024*1024 - 4096, 'i386' => 64*1024*1024 - 4096, diff --git a/Zend/zend_call_stack.c b/Zend/zend_call_stack.c index bbaa8810af9e1..8e0ce4c32488a 100644 --- a/Zend/zend_call_stack.c +++ b/Zend/zend_call_stack.c @@ -417,7 +417,9 @@ static bool zend_call_stack_get_macos(zend_call_stack *stack) void *base = pthread_get_stackaddr_np(pthread_self()); size_t max_size; - if (pthread_main_np()) { +#if !defined(__aarch64__) + if (pthread_main_np()) + { /* pthread_get_stacksize_np() returns a too low value for the main * thread in OSX 10.9, 10.10: * https://mail.openjdk.org/pipermail/hotspot-dev/2013-October/011353.html @@ -427,7 +429,10 @@ static bool zend_call_stack_get_macos(zend_call_stack *stack) /* Stack size is 8MiB by default for main threads * https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Multithreading/CreatingThreads/CreatingThreads.html */ max_size = 8 * 1024 * 1024; - } else { + } + else +#endif + { max_size = pthread_get_stacksize_np(pthread_self()); }