Skip to content

Commit f64086a

Browse files
committed
Increase zend.reserved_stack_size minimum value in ASAN/MSAN builds
1 parent 72a163a commit f64086a

16 files changed

+85
-21
lines changed

Zend/tests/stack_limit/stack_limit_001.phpt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ Stack limit 001 - Stack limit checks with max_allowed_stack_size detection
33
--SKIPIF--
44
<?php
55
if (!function_exists('zend_test_zend_call_stack_get')) die("skip zend_test_zend_call_stack_get() is not available");
6-
if (getenv('SKIP_MSAN')) die("skip msan requires a considerably higher zend.reserved_stack_size due to instrumentation");
76
?>
87
--EXTENSIONS--
98
zend_test

Zend/tests/stack_limit/stack_limit_002.phpt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ Stack limit 002 - Stack limit checks with max_allowed_stack_size detection (fibe
33
--SKIPIF--
44
<?php
55
if (!function_exists('zend_test_zend_call_stack_get')) die("skip zend_test_zend_call_stack_get() is not available");
6-
if (getenv('SKIP_MSAN')) die("skip msan requires a considerably higher zend.reserved_stack_size due to instrumentation");
76
?>
87
--EXTENSIONS--
98
zend_test

Zend/tests/stack_limit/stack_limit_003.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ if (!function_exists('zend_test_zend_call_stack_get')) die("skip zend_test_zend_
77
--EXTENSIONS--
88
zend_test
99
--INI--
10-
zend.max_allowed_stack_size=128K
10+
zend.max_allowed_stack_size=512K
1111
--FILE--
1212
<?php
1313

Zend/tests/stack_limit/stack_limit_004.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,12 @@ $callback = function (): int {
2727
throw new \Exception();
2828
};
2929

30-
ini_set('fiber.stack_size', '400K');
30+
ini_set('fiber.stack_size', '1M');
3131
$fiber = new Fiber($callback);
3232
$fiber->start();
3333
$depth1 = $fiber->getReturn();
3434

35-
ini_set('fiber.stack_size', '200K');
35+
ini_set('fiber.stack_size', '512K');
3636
$fiber = new Fiber($callback);
3737
$fiber->start();
3838
$depth2 = $fiber->getReturn();

Zend/tests/stack_limit/stack_limit_006.phpt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ Stack limit 006 - env size affects __libc_stack_end
33
--SKIPIF--
44
<?php
55
if (!function_exists('zend_test_zend_call_stack_get')) die("skip zend_test_zend_call_stack_get() is not available");
6-
if (getenv('SKIP_MSAN')) die("skip msan requires a considerably higher zend.reserved_stack_size due to instrumentation");
76
?>
87
--EXTENSIONS--
98
zend_test

Zend/tests/stack_limit/stack_limit_007.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ if (!function_exists('zend_test_zend_call_stack_get')) die("skip zend_test_zend_
77
--EXTENSIONS--
88
zend_test
99
--INI--
10-
zend.max_allowed_stack_size=128K
10+
zend.max_allowed_stack_size=512K
1111
--FILE--
1212
<?php
1313

Zend/tests/stack_limit/stack_limit_008.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ if (!function_exists('zend_test_zend_call_stack_get')) die("skip zend_test_zend_
77
--EXTENSIONS--
88
zend_test
99
--INI--
10-
zend.max_allowed_stack_size=128K
10+
zend.max_allowed_stack_size=512K
1111
--FILE--
1212
<?php
1313

Zend/tests/stack_limit/stack_limit_009.phpt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ Stack limit 009 - Check that we can actually use all the stack
33
--SKIPIF--
44
<?php
55
if (!function_exists('zend_test_zend_call_stack_get')) die("skip zend_test_zend_call_stack_get() is not available");
6-
if (getenv('SKIP_MSAN')) die("skip msan requires a considerably higher zend.reserved_stack_size due to instrumentation");
76
?>
87
--EXTENSIONS--
98
zend_test

Zend/tests/stack_limit/stack_limit_011.phpt

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,27 @@ if (!function_exists('zend_test_zend_call_stack_get')) die("skip zend_test_zend_
77
--EXTENSIONS--
88
zend_test
99
--INI--
10-
zend.max_allowed_stack_size=128K
10+
zend.max_allowed_stack_size=512K
1111
--FILE--
1212
<?php
1313

1414
var_dump(zend_test_zend_call_stack_get());
1515

16-
class Test1 {
17-
public function __destruct() {
18-
new Test1;
19-
}
16+
function replace2() {
17+
return preg_replace_callback('#.#', function () {
18+
replace2();
19+
}, 'x');
2020
}
21-
2221
function replace() {
23-
return preg_replace_callback('#.#', function () {
22+
static $once = false;
23+
return preg_replace_callback('#.#', function () use (&$once) {
2424
try {
2525
replace();
2626
} finally {
27-
new Test1();
27+
if (!$once) {
28+
$once = true;
29+
replace2();
30+
}
2831
}
2932
}, 'x');
3033
}

Zend/tests/stack_limit/stack_limit_012.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ if (!function_exists('zend_test_zend_call_stack_get')) die("skip zend_test_zend_
77
--EXTENSIONS--
88
zend_test
99
--INI--
10-
zend.max_allowed_stack_size=128K
10+
zend.max_allowed_stack_size=512K
1111
--FILE--
1212
<?php
1313

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
if (!class_exists("constructs_in_destructor")) {
4+
class constructs_in_destructor {
5+
public function __destruct() {
6+
$a = new constructs_in_destructor;
7+
$time = '';
8+
require(__FILE__);
9+
}
10+
}
11+
}
12+
13+
$a = new constructs_in_destructor;
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
if (!class_exists("constructs_in_destructor")) {
4+
class constructs_in_destructor {
5+
public function __destruct() {
6+
$a = new constructs_in_destructor;
7+
$time = '';
8+
require(__FILE__);
9+
}
10+
}
11+
}
12+
13+
$a = new constructs_in_destructor;
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
--TEST--
2+
Stack limit 014 - Fuzzer
3+
--SKIPIF--
4+
<?php
5+
if (!function_exists('zend_test_zend_call_stack_get')) die("skip zend_test_zend_call_stack_get() is not available");
6+
?>
7+
--EXTENSIONS--
8+
zend_test
9+
--INI--
10+
; The test may use a large amount of memory on systems with a large stack limit
11+
memory_limit=1G
12+
--FILE--
13+
<?php
14+
15+
try {
16+
require __DIR__.'/stack_limit_014.inc';
17+
} catch (Error $e) {
18+
echo $e->getMessage(), "\n";
19+
}
20+
21+
?>
22+
--EXPECTF--
23+
%S%rMaximum call stack size of [0-9]+ bytes reached|Allowed memory size of [0-9]+ bytes exhausted%r%s

Zend/zend.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,12 @@ static ZEND_INI_MH(OnUpdateReservedStackSize) /* {{{ */
206206
zend_ulong min = 32*1024;
207207
#endif
208208

209+
#if defined(__SANITIZE_ADDRESS__) || __has_feature(memory_sanitizer)
210+
/* AddressSanitizer and MemorySanitizer use more stack due to
211+
* instrumentation */
212+
min *= 10;
213+
#endif
214+
209215
if (size == 0) {
210216
size = min;
211217
} else if (size < min) {

Zend/zend_compile.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,14 @@ static void zend_compile_assign(znode *result, zend_ast *ast);
102102
#ifdef ZEND_CHECK_STACK_LIMIT
103103
zend_never_inline static void zend_stack_limit_error(void)
104104
{
105+
size_t max_stack_size = 0;
106+
if ((uintptr_t) EG(stack_base) > (uintptr_t) EG(stack_limit)) {
107+
max_stack_size = (size_t) ((uintptr_t) EG(stack_base) - (uintptr_t) EG(stack_limit));
108+
}
109+
105110
zend_error_noreturn(E_COMPILE_ERROR,
106111
"Maximum call stack size of %zu bytes reached during compilation. Try splitting expression",
107-
(size_t) ((uintptr_t) EG(stack_base) - (uintptr_t) EG(stack_limit)));
112+
max_stack_size);
108113
}
109114

110115
static void zend_check_stack_limit(void)

Zend/zend_execute.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2308,8 +2308,13 @@ static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_use_new_element_for_s
23082308
#ifdef ZEND_CHECK_STACK_LIMIT
23092309
static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_call_stack_size_error(void)
23102310
{
2311-
zend_throw_error(NULL, "Maximum call stack size of %zu bytes reached. Infinite recursion?",
2312-
(size_t) ((uintptr_t) EG(stack_base) - (uintptr_t) EG(stack_limit)));
2311+
size_t max_stack_size = 0;
2312+
if ((uintptr_t) EG(stack_base) > (uintptr_t) EG(stack_limit)) {
2313+
max_stack_size = (size_t) ((uintptr_t) EG(stack_base) - (uintptr_t) EG(stack_limit));
2314+
}
2315+
zend_throw_error(NULL,
2316+
"Maximum call stack size of %zu bytes reached. Infinite recursion?",
2317+
max_stack_size);
23132318
}
23142319
#endif /* ZEND_CHECK_STACK_LIMIT */
23152320

0 commit comments

Comments
 (0)