From eef0fa359934f2515fe1d8f5d88c9ac4493de460 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sun, 3 Mar 2024 22:37:12 +0000 Subject: [PATCH 1/2] zend call stack adjust case for freebsd to calculate the guard size. it was not wrong but there is a sysctl oid storing the number of guard pages, which is 1 by default but is modifiable at runtime. --- Zend/zend_call_stack.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/Zend/zend_call_stack.c b/Zend/zend_call_stack.c index ad6c1932553a9..7cb15baafc1a1 100644 --- a/Zend/zend_call_stack.c +++ b/Zend/zend_call_stack.c @@ -313,6 +313,7 @@ static bool zend_call_stack_get_freebsd_sysctl(zend_call_stack *stack) int mib[2] = {CTL_KERN, KERN_USRSTACK}; size_t len = sizeof(stack_base); struct rlimit rlim; + static size_t numguards = (size_t)-1; /* This method is relevant only for the main thread */ ZEND_ASSERT(zend_call_stack_is_main_thread()); @@ -329,7 +330,17 @@ static bool zend_call_stack_get_freebsd_sysctl(zend_call_stack *stack) return false; } - size_t guard_size = getpagesize(); + if (numguards == (size_t)-1) { + size_t tmpguards = 0; + len = sizeof(tmpguards); + /* For most of the cases, we do not necessarily need to do so as, by default, it is `1` page, but is user writable */ + if (sysctlbyname("security.bsd.stack_guard_page", &tmpguards, &len, NULL, 0) != 0) { + return false; + } + numguards = tmpguards; + } + + size_t guard_size = numguards * getpagesize(); stack->base = stack_base; stack->max_size = rlim.rlim_cur - guard_size; From 7c5425f45c3a41780a6e4e909df8df8f31ad6ba4 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Mon, 4 Mar 2024 18:22:20 +0000 Subject: [PATCH 2/2] remove static var. --- Zend/zend_call_stack.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/Zend/zend_call_stack.c b/Zend/zend_call_stack.c index 7cb15baafc1a1..97cbed9041431 100644 --- a/Zend/zend_call_stack.c +++ b/Zend/zend_call_stack.c @@ -313,7 +313,7 @@ static bool zend_call_stack_get_freebsd_sysctl(zend_call_stack *stack) int mib[2] = {CTL_KERN, KERN_USRSTACK}; size_t len = sizeof(stack_base); struct rlimit rlim; - static size_t numguards = (size_t)-1; + size_t numguards = 0; /* This method is relevant only for the main thread */ ZEND_ASSERT(zend_call_stack_is_main_thread()); @@ -330,14 +330,10 @@ static bool zend_call_stack_get_freebsd_sysctl(zend_call_stack *stack) return false; } - if (numguards == (size_t)-1) { - size_t tmpguards = 0; - len = sizeof(tmpguards); - /* For most of the cases, we do not necessarily need to do so as, by default, it is `1` page, but is user writable */ - if (sysctlbyname("security.bsd.stack_guard_page", &tmpguards, &len, NULL, 0) != 0) { - return false; - } - numguards = tmpguards; + len = sizeof(numguards); + /* For most of the cases, we do not necessarily need to do so as, by default, it is `1` page, but is user writable */ + if (sysctlbyname("security.bsd.stack_guard_page", &numguards, &len, NULL, 0) != 0) { + return false; } size_t guard_size = numguards * getpagesize();