[php-src] PHP-8.2: Preserve bare NUL access with open_basedir on Windows (#24158)
| From: | Shivam Mathur via GitHub | Date: | Tue, 06 Oct 2026 12:53:44 +0000 |
| Subject: | [php-src] PHP-8.2: Preserve bare NUL access with open_basedir on Windows (#24158) | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-142000@lists.php.net to get a copy of this message | ||
Author: Shivam Mathur (shivammathur)
Committer: GitHub (web-flow)
Pusher: shivammathur
Date: 2026-10-06T18:23:41+05:30
Commit: https://github.com/php/php-src/commit/1b47a92963546d8fbcaa8e0960ae9794c35d265c
Raw diff: https://github.com/php/php-src/commit/1b47a92963546d8fbcaa8e0960ae9794c35d265c.diff
Preserve bare NUL access with open_basedir on Windows (#24158)
Changed paths:
A tests/security/open_basedir_nul_win32.phpt
M main/fopen_wrappers.c
Diff:
diff --git a/main/fopen_wrappers.c b/main/fopen_wrappers.c
index ebe57153facf..d62d0cc1b2bf 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 000000000000..d1856823069f
--- /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)