Skip to content

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

Closed

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

  1. added a commit that references this issue on Sep 29, 2026
    023ee4d
  2. added 3 commits that reference this issue on Sep 29, 2026
    35a9f77
    cf8eefb
    008a001
  3. added a commit that references this issue on Sep 29, 2026
    4d5cb1d
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