Skip to content

Commit 9da75d0

Browse files
authored
fix: no-op when signal handlers are called on threads not managed by PHP (#9766)
1 parent 77eadc5 commit 9da75d0

File tree

5 files changed

+21
-1
lines changed

5 files changed

+21
-1
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ PHP NEWS
1212
. SA_ONSTACK is now set for signal handlers to be friendlier to other
1313
in-process code such as Go's cgo. (Kévin Dunglas)
1414
. SA_ONSTACK is now set when signals are disabled. (Kévin Dunglas)
15+
. Fix GH-9649: Signal handlers now do a no-op instead of crashing when
16+
executed on threads not managed by TSRM. (Kévin Dunglas)
1517

1618
- Fileinfo:
1719
. Upgrade bundled libmagic to 5.43. (Anatol)

TSRM/TSRM.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -779,4 +779,9 @@ TSRM_API const char *tsrm_api_name(void)
779779
#endif
780780
}/*}}}*/
781781

782+
TSRM_API bool tsrm_is_managed_thread()
783+
{/*{{{*/
784+
return tsrm_tls_get() ? true : false;
785+
}/*}}}*/
786+
782787
#endif /* ZTS */

TSRM/TSRM.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ TSRM_API size_t tsrm_get_ls_cache_tcb_offset(void);
137137
TSRM_API bool tsrm_is_main_thread(void);
138138
TSRM_API bool tsrm_is_shutdown(void);
139139
TSRM_API const char *tsrm_api_name(void);
140+
TSRM_API bool tsrm_is_managed_thread(void);
140141

141142
#ifdef TSRM_WIN32
142143
# define TSRM_TLS __declspec(thread)

Zend/zend_execute_API.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1355,7 +1355,13 @@ ZEND_API ZEND_NORETURN void ZEND_FASTCALL zend_timeout(void) /* {{{ */
13551355
#ifndef ZEND_WIN32
13561356
static void zend_timeout_handler(int dummy) /* {{{ */
13571357
{
1358-
#ifndef ZTS
1358+
#ifdef ZTS
1359+
if (!tsrm_is_managed_thread()) {
1360+
fprintf(stderr, "zend_timeout_handler() called in a thread not managed by PHP. The expected signal handler will not be called. This is probably a bug.\n");
1361+
1362+
return;
1363+
}
1364+
#else
13591365
if (zend_atomic_bool_load_ex(&EG(timed_out))) {
13601366
/* Die on hard timeout */
13611367
const char *error_filename = NULL;

Zend/zend_signal.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,12 @@ void zend_signal_handler_defer(int signo, siginfo_t *siginfo, void *context)
8787
zend_signal_queue_t *queue, *qtmp;
8888

8989
#ifdef ZTS
90+
if (!tsrm_is_managed_thread()) {
91+
fprintf(stderr, "zend_signal_handler_defer() called in a thread not managed by PHP. The expected signal handler will not be called. This is probably a bug.\n");
92+
93+
return;
94+
}
95+
9096
/* A signal could hit after TSRM shutdown, in this case globals are already freed. */
9197
if (tsrm_is_shutdown()) {
9298
/* Forward to default handler handler */

0 commit comments

Comments
 (0)