Skip to content

Commit db2ac3a

Browse files
committed
Merge branch 'PHP-8.2'
* PHP-8.2: Fix use of uninitialized memory in pcntl SIGCHLD handling
2 parents 1358b43 + 7d18849 commit db2ac3a

File tree

2 files changed

+17
-13
lines changed

2 files changed

+17
-13
lines changed

ext/pcntl/pcntl.c

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1048,15 +1048,13 @@ static void pcntl_signal_handler(int signo, siginfo_t *siginfo, void *context)
10481048
static void pcntl_signal_handler(int signo)
10491049
#endif
10501050
{
1051-
struct php_pcntl_pending_signal *psig;
1052-
1053-
psig = PCNTL_G(spares);
1054-
if (!psig) {
1051+
struct php_pcntl_pending_signal *psig_first = PCNTL_G(spares);
1052+
if (!psig_first) {
10551053
/* oops, too many signals for us to track, so we'll forget about this one */
10561054
return;
10571055
}
10581056

1059-
struct php_pcntl_pending_signal *psig_first = psig;
1057+
struct php_pcntl_pending_signal *psig = NULL;
10601058

10611059
/* Standard signals may be merged into a single one.
10621060
* POSIX specifies that SIGCHLD has the si_pid field (https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html),
@@ -1075,28 +1073,27 @@ static void pcntl_signal_handler(int signo)
10751073
pid = waitpid(WAIT_ANY, &status, WNOHANG | WUNTRACED);
10761074
} while (pid <= 0 && errno == EINTR);
10771075
if (pid <= 0) {
1078-
if (UNEXPECTED(psig == psig_first)) {
1079-
/* Don't handle multiple, revert back to the single signal handling. */
1080-
goto single_signal;
1076+
if (UNEXPECTED(!psig)) {
1077+
/* The child might've been consumed by another thread and will be handled there. */
1078+
return;
10811079
}
10821080
break;
10831081
}
10841082

1083+
psig = psig ? psig->next : psig_first;
10851084
psig->signo = signo;
10861085

10871086
#ifdef HAVE_STRUCT_SIGINFO_T
10881087
psig->siginfo = *siginfo;
10891088
psig->siginfo.si_pid = pid;
10901089
#endif
10911090

1092-
if (EXPECTED(psig->next)) {
1093-
psig = psig->next;
1094-
} else {
1091+
if (UNEXPECTED(!psig->next)) {
10951092
break;
10961093
}
10971094
}
10981095
} else {
1099-
single_signal:;
1096+
psig = psig_first;
11001097
psig->signo = signo;
11011098

11021099
#ifdef HAVE_STRUCT_SIGINFO_T

ext/pcntl/tests/gh11498.phpt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,11 @@ $processes = [];
1414

1515
pcntl_async_signals(true);
1616
pcntl_signal(SIGCHLD, function($sig, $info) use (&$processes) {
17+
echo "SIGCHLD\n";
1718
unset($processes[$info['pid']]);
1819
}, false);
1920

20-
foreach (range(0, 5) as $i) {
21+
for ($i = 0; $i <= 5; $i++) {
2122
$process = proc_open('echo $$ > /dev/null', [], $pipes);
2223
$pid = proc_get_status($process)['pid'];
2324
$processes[$pid] = $process;
@@ -32,4 +33,10 @@ while (!empty($processes) && $iters > 0) {
3233
var_dump(empty($processes));
3334
?>
3435
--EXPECT--
36+
SIGCHLD
37+
SIGCHLD
38+
SIGCHLD
39+
SIGCHLD
40+
SIGCHLD
41+
SIGCHLD
3542
bool(true)

0 commit comments

Comments
 (0)