Commit 1b47a929635 for php
commit 1b47a92963546d8fbcaa8e0960ae9794c35d265c
Author: Shivam Mathur <shivam_jpr@hotmail.com>
Date: Tue Oct 6 18:23:41 2026 +0530
Preserve bare NUL access with open_basedir on Windows (#24158)
diff --git a/main/fopen_wrappers.c b/main/fopen_wrappers.c
index ebe57153fac..d62d0cc1b2b 100644
--- a/main/fopen_wrappers.c
+++ b/main/fopen_wrappers.c
@@ -139,6 +139,14 @@ PHPAPI int php_check_specific_open_basedir(const char *basedir, const char *path
size_t path_len;
int nesting_level = 0;
+#ifdef PHP_WIN32
+ /* Preserve the working-directory permission check for bare NUL. */
+ if ((strcasecmp(path, "NUL") == 0 || strcasecmp(path, "NUL:") == 0)
+ && php_check_specific_open_basedir(basedir, ".") == 0) {
+ return 0;
+ }
+#endif
+
/* Special case basedir==".": Use script-directory */
if (strcmp(basedir, ".") || !VCWD_GETCWD(local_open_basedir, MAXPATHLEN)) {
/* Else use the unmodified path */
diff --git a/tests/security/open_basedir_nul_win32.phpt b/tests/security/open_basedir_nul_win32.phpt
new file mode 100644
index 00000000000..d1856823069
--- /dev/null
+++ b/tests/security/open_basedir_nul_win32.phpt
@@ -0,0 +1,57 @@
+--TEST--
+GH-24148: Bare NUL remains usable with open_basedir on Windows
+--SKIPIF--
+<?php
+if (PHP_OS_FAMILY !== 'Windows') die('skip Windows only');
+if (!function_exists('proc_open')) die('skip proc_open unavailable');
+?>
+--INI--
+open_basedir=
+--FILE--
+<?php
+chdir(__DIR__);
+foreach ([
+ 'Directory allowed' => __DIR__,
+ 'Devices explicitly allowed' => __FILE__ . ';NUL;NUL:',
+ 'Only file allowed' => __FILE__,
+] as $label => $basedir) {
+ echo "$label:\n";
+ var_dump(ini_set('open_basedir', $basedir) !== false);
+ foreach (['NUL', 'nul:'] as $name) {
+ $stream = @fopen($name, 'c');
+ var_dump(is_resource($stream));
+ if (is_resource($stream)) {
+ fclose($stream);
+ }
+ }
+ $process = @proc_open('cmd /c exit 0', [
+ ['pipe', 'r'], ['file', 'NUL', 'w'], ['file', 'nul:', 'w'],
+ ], $pipes);
+ if (is_resource($process)) {
+ fclose($pipes[0]);
+ var_dump(proc_close($process) === 0);
+ } else {
+ var_dump(false);
+ }
+ var_dump(file_get_contents(__FILE__) !== false);
+}
+?>
+--EXPECT--
+Directory allowed:
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+Devices explicitly allowed:
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+Only file allowed:
+bool(true)
+bool(false)
+bool(false)
+bool(false)
+bool(true)