From 07eb8fb0efec9afc5b970af268b565ad667e7271 Mon Sep 17 00:00:00 2001 From: Aaron Piotrowski Date: Sat, 16 Jul 2022 10:13:32 -0500 Subject: [PATCH 1/3] Prevent switching fibers in tick function --- Zend/tests/fibers/ticks.phpt | 33 +++++++++++++++++++++++++++++++++ Zend/zend_vm_def.h | 2 ++ Zend/zend_vm_execute.h | 2 ++ 3 files changed, 37 insertions(+) create mode 100644 Zend/tests/fibers/ticks.phpt diff --git a/Zend/tests/fibers/ticks.phpt b/Zend/tests/fibers/ticks.phpt new file mode 100644 index 0000000000000..89b0836547fbf --- /dev/null +++ b/Zend/tests/fibers/ticks.phpt @@ -0,0 +1,33 @@ +--TEST-- +Prevent switchcing fibers in tick function +--FILE-- +start(); + +?> +--EXPECTF-- +1 + +Fatal error: Uncaught FiberError: Cannot switch fibers in current execution context in %sticks.php:%d +Stack trace: +#0 %sticks.php(%d): Fiber::suspend() +#1 %sticks.php(%d): {closure}() +#2 [internal function]: {closure}() +#3 %sticks.php(%d): Fiber->start() +#4 {main} + thrown in %sticks.php on line %d diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 9043cde725bac..86557b6e2bf11 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -7752,7 +7752,9 @@ ZEND_VM_HANDLER(105, ZEND_TICKS, ANY, ANY, NUM) EG(ticks_count) = 0; if (zend_ticks_function) { SAVE_OPLINE(); + zend_fiber_switch_block(); zend_ticks_function(opline->extended_value); + zend_fiber_switch_unblock(); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 39005c9184946..13ba74433602f 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -2996,7 +2996,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_TICKS_SPEC_HANDLER(ZEND_OPCODE EG(ticks_count) = 0; if (zend_ticks_function) { SAVE_OPLINE(); + zend_fiber_switch_block(); zend_ticks_function(opline->extended_value); + zend_fiber_switch_unblock(); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } } From 6baf54376b64913425157ee8ca6cb275f8360075 Mon Sep 17 00:00:00 2001 From: Aaron Piotrowski Date: Sat, 16 Jul 2022 10:14:04 -0500 Subject: [PATCH 2/3] Prevent switching fibers when handling a signal --- Zend/tests/fibers/signal-async.phpt | 37 +++++++++++++++++++++ Zend/tests/fibers/signal-dispatch.phpt | 46 ++++++++++++++++++++++++++ ext/pcntl/pcntl.c | 7 ++++ 3 files changed, 90 insertions(+) create mode 100644 Zend/tests/fibers/signal-async.phpt create mode 100644 Zend/tests/fibers/signal-dispatch.phpt diff --git a/Zend/tests/fibers/signal-async.phpt b/Zend/tests/fibers/signal-async.phpt new file mode 100644 index 0000000000000..babe3ba48f740 --- /dev/null +++ b/Zend/tests/fibers/signal-async.phpt @@ -0,0 +1,37 @@ +--TEST-- +Prevent switchcing fibers when async signals are enabled +--EXTENSIONS-- +pcntl +posix +--FILE-- +start(); + +?> +--EXPECTF-- +Fiber start + +Fatal error: Uncaught FiberError: Cannot switch fibers in current execution context in %ssignal-async.php:%d +Stack trace: +#0 %ssignal-async.php(%d): Fiber::suspend() +#1 %ssignal-async.php(%d): {closure}(%d, Array) +#2 [internal function]: {closure}() +#3 %ssignal-async.php(%d): Fiber->start() +#4 {main} + thrown in %ssignal-async.php on line %d diff --git a/Zend/tests/fibers/signal-dispatch.phpt b/Zend/tests/fibers/signal-dispatch.phpt new file mode 100644 index 0000000000000..d076fb4509a08 --- /dev/null +++ b/Zend/tests/fibers/signal-dispatch.phpt @@ -0,0 +1,46 @@ +--TEST-- +Prevent switchcing fibers when dispatching pending signals +--EXTENSIONS-- +pcntl +posix +--FILE-- +start(); + +echo $e, "\n"; + +$fiber->resume(); + +?> +--EXPECTF-- +Fiber start +FiberError: Cannot switch fibers in current execution context in %ssignal-dispatch.php:%d +Stack trace: +#0 %ssignal-dispatch.php(%d): Fiber::suspend() +#1 [internal function]: {closure}(%d, Array) +#2 %ssignal-dispatch.php(%d): pcntl_signal_dispatch() +#3 [internal function]: {closure}() +#4 %ssignal-dispatch.php(%d): Fiber->start() +#5 {main} +Fiber end diff --git a/ext/pcntl/pcntl.c b/ext/pcntl/pcntl.c index fe4fe104a3621..e1aedb101c913 100644 --- a/ext/pcntl/pcntl.c +++ b/ext/pcntl/pcntl.c @@ -34,6 +34,7 @@ #include "pcntl_arginfo.h" #include "php_signal.h" #include "php_ticks.h" +#include "zend_fibers.h" #if defined(HAVE_GETPRIORITY) || defined(HAVE_SETPRIORITY) || defined(HAVE_WAIT3) #include @@ -1410,6 +1411,9 @@ void pcntl_signal_dispatch() return; } + /* Prevent switching fibers when handling signals */ + zend_fiber_switch_block(); + /* Prevent reentrant handler calls */ PCNTL_G(processing_signal_queue) = 1; @@ -1450,6 +1454,9 @@ void pcntl_signal_dispatch() /* Re-enable queue */ PCNTL_G(processing_signal_queue) = 0; + /* Re-enable fiber switching */ + zend_fiber_switch_unblock(); + /* return signal mask to previous state */ sigprocmask(SIG_SETMASK, &old_mask, NULL); } From d164c5390e492040cf5080250acd878b6aa3f6dd Mon Sep 17 00:00:00 2001 From: Aaron Piotrowski Date: Sat, 16 Jul 2022 10:58:49 -0500 Subject: [PATCH 3/3] Fix typo Thanks @staabm --- Zend/tests/fibers/signal-async.phpt | 2 +- Zend/tests/fibers/signal-dispatch.phpt | 2 +- Zend/tests/fibers/ticks.phpt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Zend/tests/fibers/signal-async.phpt b/Zend/tests/fibers/signal-async.phpt index babe3ba48f740..f1f5a2f4c8f2d 100644 --- a/Zend/tests/fibers/signal-async.phpt +++ b/Zend/tests/fibers/signal-async.phpt @@ -1,5 +1,5 @@ --TEST-- -Prevent switchcing fibers when async signals are enabled +Prevent switching fibers when async signals are enabled --EXTENSIONS-- pcntl posix diff --git a/Zend/tests/fibers/signal-dispatch.phpt b/Zend/tests/fibers/signal-dispatch.phpt index d076fb4509a08..abde8e313d76e 100644 --- a/Zend/tests/fibers/signal-dispatch.phpt +++ b/Zend/tests/fibers/signal-dispatch.phpt @@ -1,5 +1,5 @@ --TEST-- -Prevent switchcing fibers when dispatching pending signals +Prevent switching fibers when dispatching pending signals --EXTENSIONS-- pcntl posix diff --git a/Zend/tests/fibers/ticks.phpt b/Zend/tests/fibers/ticks.phpt index 89b0836547fbf..fbd050c09b950 100644 --- a/Zend/tests/fibers/ticks.phpt +++ b/Zend/tests/fibers/ticks.phpt @@ -1,5 +1,5 @@ --TEST-- -Prevent switchcing fibers in tick function +Prevent switching fibers in tick function --FILE--