Skip to content

/proc/self paths resolve to the parent process after pcntl_fork() (realpath cache) #23986

Description

@frodeborli

Description

After pcntl_fork(), a path under /proc/self that the parent already used resolves, in the child, to the parent's /proc/<pid>: the realpath cache kept the resolved symlink across the fork. The child reads the parent's process information.

<?php
$pid = fn() => (int) explode(' ', file_get_contents('/proc/self/stat'))[0];
echo "parent: ", $pid() === getmypid() ? "ok" : "wrong", "\n";
if (pcntl_fork() === 0) {
    echo "child: /proc/self/stat says ", $pid(), ", getmypid() ", getmypid(), "\n";
    exit(0);
}
pcntl_wait($status);

Resulted in this output:

parent: ok
child: /proc/self/stat says 3248499, getmypid() 3248500

But I expected this output instead:

parent: ok
child: /proc/self/stat says 3248500, getmypid() 3248500

clearstatcache(true) in the child works around it. The same happens with scandir('/proc/self/task') and the like, on NTS and ZTS builds. /proc/self (and /proc/thread-self) are symlinks whose target depends on the process reading them, so they shouldn't be cached, or the realpath cache could be cleared in the child of pcntl_fork().

PHP Version

PHP 8.5.11 (cli) (NTS); also 8.4.26 (cli) (ZTS)

Operating System

Ubuntu 24.04 (x86_64); Alpine 3.22 (Docker)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions