Skip to content

Commit 183f71a

Browse files
committed
Fix use of uninitialized memory in pcntl SIGCHLD handling
psig needs to stay the tail, so that we don't get a dangling element on the end.
1 parent 8ec5a10 commit 183f71a

File tree

2 files changed

+9
-14
lines changed

2 files changed

+9
-14
lines changed

ext/pcntl/pcntl.c

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1338,15 +1338,13 @@ static void pcntl_signal_handler(int signo, siginfo_t *siginfo, void *context)
13381338
static void pcntl_signal_handler(int signo)
13391339
#endif
13401340
{
1341-
struct php_pcntl_pending_signal *psig;
1342-
1343-
psig = PCNTL_G(spares);
1344-
if (!psig) {
1341+
struct php_pcntl_pending_signal *psig_first = PCNTL_G(spares);
1342+
if (!psig_first) {
13451343
/* oops, too many signals for us to track, so we'll forget about this one */
13461344
return;
13471345
}
13481346

1349-
struct php_pcntl_pending_signal *psig_first = psig;
1347+
struct php_pcntl_pending_signal *psig = NULL;
13501348

13511349
/* Standard signals may be merged into a single one.
13521350
* POSIX specifies that SIGCHLD has the si_pid field (https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html),
@@ -1365,28 +1363,25 @@ static void pcntl_signal_handler(int signo)
13651363
pid = waitpid(WAIT_ANY, &status, WNOHANG | WUNTRACED);
13661364
} while (pid <= 0 && errno == EINTR);
13671365
if (pid <= 0) {
1368-
if (UNEXPECTED(psig == psig_first)) {
1369-
/* Don't handle multiple, revert back to the single signal handling. */
1370-
goto single_signal;
1371-
}
1366+
/* There must've been at least one iteration so that psig is initialized. */
1367+
ZEND_ASSERT(psig != NULL);
13721368
break;
13731369
}
13741370

1371+
psig = psig ? psig->next : psig_first;
13751372
psig->signo = signo;
13761373

13771374
#ifdef HAVE_STRUCT_SIGINFO_T
13781375
psig->siginfo = *siginfo;
13791376
psig->siginfo.si_pid = pid;
13801377
#endif
13811378

1382-
if (EXPECTED(psig->next)) {
1383-
psig = psig->next;
1384-
} else {
1379+
if (UNEXPECTED(!psig->next)) {
13851380
break;
13861381
}
13871382
}
13881383
} else {
1389-
single_signal:;
1384+
psig = psig_first;
13901385
psig->signo = signo;
13911386

13921387
#ifdef HAVE_STRUCT_SIGINFO_T

ext/pcntl/tests/gh11498.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ pcntl_signal(SIGCHLD, function($sig, $info) use (&$processes) {
1717
unset($processes[$info['pid']]);
1818
}, false);
1919

20-
foreach (range(0, 5) as $i) {
20+
for ($i = 0; $i <= 5; $i++) {
2121
$process = proc_open('echo $$ > /dev/null', [], $pipes);
2222
$pid = proc_get_status($process)['pid'];
2323
$processes[$pid] = $process;

0 commit comments

Comments
 (0)