Commit 023ee4dc998 for php

commit 023ee4dc9983b036ccf889cd1cd70b0016716ef9
Author: Lazizbek Ergashev <lazerg2@gmail.com>
Date:   Tue Sep 29 21:02:57 2026 +0500

    Fix GH-23986: Clear the realpath cache in the child after pcntl_fork() (#23987)

diff --git a/NEWS b/NEWS
index 8eb6798b700..4ace934375f 100644
--- a/NEWS
+++ b/NEWS
@@ -94,6 +94,8 @@ PHP                                                                        NEWS
     the inclusive upper bound. (lacatoire)
   . Fixed pcntl_setqos_class() requiring its optional $qos_class argument.
     (lacatoire)
+  . Fixed bug GH-23986 (/proc/self paths resolve to the parent process after
+    pcntl_fork()). (Lazizbek Ergashev)

 - PDO:
   . Fixed PDOStatement::getColumnMeta() reading out of bounds for an invalid
diff --git a/ext/pcntl/pcntl.c b/ext/pcntl/pcntl.c
index 34a67028263..1858ee6e4a7 100644
--- a/ext/pcntl/pcntl.c
+++ b/ext/pcntl/pcntl.c
@@ -29,6 +29,7 @@

 #include "php.h"
 #include "ext/standard/info.h"
+#include "ext/standard/php_filestat.h"
 #include "php_signal.h"
 #include "php_ticks.h"
 #include "zend_exceptions.h"
@@ -294,6 +295,7 @@ PHP_FUNCTION(pcntl_fork)
 		}
 	} else if (id == 0) {
 		zend_max_execution_timer_init();
+		php_clear_stat_cache(true, NULL, 0);
 	}

 	RETURN_LONG((zend_long) id);
@@ -1573,6 +1575,7 @@ PHP_FUNCTION(pcntl_rfork)
 		}
 	} else if (pid == 0) {
 		zend_max_execution_timer_init();
+		php_clear_stat_cache(true, NULL, 0);
 	}

 	RETURN_LONG((zend_long) pid);
@@ -1618,6 +1621,7 @@ PHP_FUNCTION(pcntl_forkx)
 		}
 	} else if (pid == 0) {
 		zend_max_execution_timer_init();
+		php_clear_stat_cache(true, NULL, 0);
 	}

 	RETURN_LONG((zend_long) pid);
diff --git a/ext/pcntl/tests/gh23986.phpt b/ext/pcntl/tests/gh23986.phpt
new file mode 100644
index 00000000000..7b9976d5007
--- /dev/null
+++ b/ext/pcntl/tests/gh23986.phpt
@@ -0,0 +1,29 @@
+--TEST--
+GH-23986 (/proc/self paths resolve to the parent process after pcntl_fork())
+--EXTENSIONS--
+pcntl
+--SKIPIF--
+<?php
+if (!is_readable('/proc/self/stat')) die('skip /proc/self/stat not available');
+?>
+--FILE--
+<?php
+function proc_self_pid() {
+    return (int) explode(' ', file_get_contents('/proc/self/stat'))[0];
+}
+
+var_dump(proc_self_pid() === getmypid());
+$parent_inode = fileinode('/proc/self');
+
+$pid = pcntl_fork();
+if ($pid === 0) {
+    var_dump(fileinode('/proc/self') !== $parent_inode);
+    var_dump(proc_self_pid() === getmypid());
+    exit(0);
+}
+pcntl_waitpid($pid, $status);
+?>
+--EXPECT--
+bool(true)
+bool(true)
+bool(true)