Skip to content

Commit 023ee4d

Browse files
authored
Fix GH-23986: Clear the realpath cache in the child after pcntl_fork() (#23987)
1 parent 22237f2 commit 023ee4d

3 files changed

Lines changed: 35 additions & 0 deletions

File tree

‎NEWS‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ PHP NEWS
9494
the inclusive upper bound. (lacatoire)
9595
. Fixed pcntl_setqos_class() requiring its optional $qos_class argument.
9696
(lacatoire)
97+
. Fixed bug GH-23986 (/proc/self paths resolve to the parent process after
98+
pcntl_fork()). (Lazizbek Ergashev)
9799

98100
- PDO:
99101
. Fixed PDOStatement::getColumnMeta() reading out of bounds for an invalid

‎ext/pcntl/pcntl.c‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
#include "php.h"
3131
#include "ext/standard/info.h"
32+
#include "ext/standard/php_filestat.h"
3233
#include "php_signal.h"
3334
#include "php_ticks.h"
3435
#include "zend_exceptions.h"
@@ -294,6 +295,7 @@ PHP_FUNCTION(pcntl_fork)
294295
}
295296
} else if (id == 0) {
296297
zend_max_execution_timer_init();
298+
php_clear_stat_cache(true, NULL, 0);
297299
}
298300

299301
RETURN_LONG((zend_long) id);
@@ -1573,6 +1575,7 @@ PHP_FUNCTION(pcntl_rfork)
15731575
}
15741576
} else if (pid == 0) {
15751577
zend_max_execution_timer_init();
1578+
php_clear_stat_cache(true, NULL, 0);
15761579
}
15771580

15781581
RETURN_LONG((zend_long) pid);
@@ -1618,6 +1621,7 @@ PHP_FUNCTION(pcntl_forkx)
16181621
}
16191622
} else if (pid == 0) {
16201623
zend_max_execution_timer_init();
1624+
php_clear_stat_cache(true, NULL, 0);
16211625
}
16221626

16231627
RETURN_LONG((zend_long) pid);

‎ext/pcntl/tests/gh23986.phpt‎

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
--TEST--
2+
GH-23986 (/proc/self paths resolve to the parent process after pcntl_fork())
3+
--EXTENSIONS--
4+
pcntl
5+
--SKIPIF--
6+
<?php
7+
if (!is_readable('/proc/self/stat')) die('skip /proc/self/stat not available');
8+
?>
9+
--FILE--
10+
<?php
11+
function proc_self_pid() {
12+
return (int) explode(' ', file_get_contents('/proc/self/stat'))[0];
13+
}
14+
15+
var_dump(proc_self_pid() === getmypid());
16+
$parent_inode = fileinode('/proc/self');
17+
18+
$pid = pcntl_fork();
19+
if ($pid === 0) {
20+
var_dump(fileinode('/proc/self') !== $parent_inode);
21+
var_dump(proc_self_pid() === getmypid());
22+
exit(0);
23+
}
24+
pcntl_waitpid($pid, $status);
25+
?>
26+
--EXPECT--
27+
bool(true)
28+
bool(true)
29+
bool(true)

0 commit comments

Comments
 (0)