Skip to content

Commit 9be2801

Browse files
committed
Separate session GC streams across forked children
1 parent 47578bb commit 9be2801

2 files changed

Lines changed: 34 additions & 14 deletions

File tree

‎ext/session/session.c‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3443,8 +3443,9 @@ static zend_result php_session_rfc1867_callback(unsigned int event, void *event_
34433443

34443444
static void php_session_child_init(void)
34453445
{
3446-
/* Move the child's GC sequence forward without requesting new entropy. */
3447-
php_random_pcgoneseq128xslrr64_advance(PS(random).state, 1);
3446+
/* Give each child a distinct, widely separated GC sequence without requesting new entropy. */
3447+
uint64_t advance = (uint64_t) getpid() << 32;
3448+
php_random_pcgoneseq128xslrr64_advance(PS(random).state, advance);
34483449
}
34493450

34503451
zend_module_entry session_module_entry = {

‎ext/session/tests/gh22616.phpt‎

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -49,23 +49,42 @@ foreach (['unseeded', 'seeded', 'active'] as $state) {
4949
if ($state === 'active') {
5050
session_start();
5151
}
52-
$file = tempnam(sys_get_temp_dir(), 'gh22616');
53-
$pid = pcntl_fork();
54-
if ($pid === -1) {
52+
$file1 = tempnam(sys_get_temp_dir(), 'gh22616');
53+
$pid1 = pcntl_fork();
54+
if ($pid1 === -1) {
5555
throw new Exception('fork failed');
5656
}
57-
if ($pid === 0) {
58-
file_put_contents($file, sequence());
57+
if ($pid1 === 0) {
58+
file_put_contents($file1, sequence());
5959
exit;
6060
}
61+
62+
$file2 = tempnam(sys_get_temp_dir(), 'gh22616');
63+
$pid2 = pcntl_fork();
64+
if ($pid2 === -1) {
65+
throw new Exception('fork failed');
66+
}
67+
if ($pid2 === 0) {
68+
file_put_contents($file2, sequence());
69+
exit;
70+
}
71+
6172
$parent = sequence();
62-
pcntl_waitpid($pid, $status);
63-
$child = file_get_contents($file);
64-
unlink($file);
65-
$results[$state] = pcntl_wifexited($status)
66-
&& pcntl_wexitstatus($status) === 0
67-
&& strlen($child) === 256
68-
&& $parent !== $child;
73+
pcntl_waitpid($pid1, $status1);
74+
pcntl_waitpid($pid2, $status2);
75+
$child1 = file_get_contents($file1);
76+
$child2 = file_get_contents($file2);
77+
unlink($file1);
78+
unlink($file2);
79+
$results[$state] = pcntl_wifexited($status1)
80+
&& pcntl_wexitstatus($status1) === 0
81+
&& pcntl_wifexited($status2)
82+
&& pcntl_wexitstatus($status2) === 0
83+
&& strlen($child1) === 256
84+
&& strlen($child2) === 256
85+
&& $parent !== $child1
86+
&& $parent !== $child2
87+
&& $child1 !== $child2;
6988
}
7089
var_dump($results);
7190
?>

0 commit comments

Comments
 (0)