php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #53577 Regression (5.3.3-5.3.4) in open_basedir with a trailing forward slash
Submitted: 2010-12-19 23:44 UTC Modified: 2011-01-18 23:30 UTC
From: lekensteyn at gmail dot com Assigned: pajoye (profile)
Status: Closed Package: Safe Mode/open_basedir
PHP Version: 5.3.4 OS: Windows 7
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: lekensteyn at gmail dot com
New email:
PHP Version: OS:

 

 [2010-12-19 23:44 UTC] lekensteyn at gmail dot com
Description:
------------
Downloaded PHP 5.3.3 from: http://windows.php.net/downloads/releases/archives/php-5.3.3-nts-Win32-VC9-x86.zip
Downloaded PHP 5.3.4 from: http://windows.php.net/downloads/releases/php-5.3.4-nts-Win32-VC9-x86.zip

The following settings has the expected results in both PHP 5.3.3 and PHP 5.3.4
open_basedir="C:\twlan\"
open_basedir="C:\twlan"
open_basedir="C:/twlan"
open_basedir="C:/twlan\"

The following setting breaks open_basedir in PHP 5.3.4, but works fine in 5.3.3.
open_basedir="C:/twlan/"

So, the trailing forward slash on open_basedir makes every path invalid.

Changes between 5.3.3 and 5.3.4:
http://svn.php.net/viewvc/php/php-src/branches/PHP_5_3/main/fopen_wrappers.c?r1=301440&r2=306091

I think the bug was introduced in http://svn.php.net/viewvc/php/php-src/trunk/main/fopen_wrappers.c?r1=305098&r2=305698
--- begin code ---
@@ -228,6 +234,9 @@
 				resolved_basedir[resolved_basedir_len] = PHP_DIR_SEPARATOR;
 				resolved_basedir[++resolved_basedir_len] = '\0';
 			}
+		} else {
+				resolved_basedir[resolved_basedir_len++] = PHP_DIR_SEPARATOR;
+				resolved_basedir[resolved_basedir_len] = '\0';
 		}
 
 		resolved_name_len = strlen(resolved_name);
--- end code ---
PHP_DIR_SEPARATOR is "\\" on Windows.

Test script:
---------------
<?php
// open_basedir="C:/twlan/"
header("Content-Type: text/plain");
error_reporting(E_ALL | E_STRICT);
ini_set('html_errors', 0);
var_dump(realpath('.'));
var_dump(realpath('..'));
var_dump(realpath('../..'));
var_dump(realpath('../../..'));
?>

Expected result:
----------------
string(22) "C:\twlan\htdocs\combot"
string(15) "C:\twlan\htdocs"
string(8) "C:\twlan"

Warning: realpath(): open_basedir restriction in effect. File(C:\) is not within the allowed path(s): (C:/twlan/) in C:\twlan\htdocs\combot\php-bug.php on line 7
bool(false)


Actual result:
--------------
Warning: realpath(): open_basedir restriction in effect. File(C:\twlan\htdocs) is not within the allowed path(s): (C:/twlan/) in C:\twlan\htdocs\combot\php-bug.php on line 5
bool(false)

Warning: realpath(): open_basedir restriction in effect. File(C:\twlan\htdocs) is not within the allowed path(s): (C:/twlan/) in C:\twlan\htdocs\combot\php-bug.php on line 5
bool(false)

Warning: realpath(): open_basedir restriction in effect. File(C:\twlan) is not within the allowed path(s): (C:/twlan/) in C:\twlan\htdocs\combot\php-bug.php on line 6
bool(false)

Warning: realpath(): open_basedir restriction in effect. File(C:\) is not within the allowed path(s): (C:/twlan/) in C:\twlan\htdocs\combot\php-bug.php on line 7
bool(false)


Patches

open_basedir-trailing-slash-fix-PHP_5_3 (last revision 2010-12-20 16:36 UTC by lekensteyn at gmail dot com)

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-12-19 23:58 UTC] lekensteyn at gmail dot com
I'm just guessing, replacing the following:
-- snip --
		if (basedir[strlen(basedir) - 1] == PHP_DIR_SEPARATOR) {
			if (resolved_basedir[resolved_basedir_len - 1] != PHP_DIR_SEPARATOR) {
				resolved_basedir[resolved_basedir_len] = PHP_DIR_SEPARATOR;
				resolved_basedir[++resolved_basedir_len] = '\0';
			}
		} else {
				resolved_basedir[resolved_basedir_len++] = PHP_DIR_SEPARATOR;
				resolved_basedir[resolved_basedir_len] = '\0';
		}
-- snip --
with
-- snip --
		if (basedir[strlen(basedir) - 1] == PHP_DIR_SEPARATOR) {
			if (resolved_basedir[resolved_basedir_len - 1] != PHP_DIR_SEPARATOR) {
				resolved_basedir[resolved_basedir_len] = PHP_DIR_SEPARATOR;
				resolved_basedir[++resolved_basedir_len] = '\0';
			}
#if defined(PHP_WIN32) || defined(NETWARE)
		} else if (basedir[strlen(basedir) - 1] != '/') {
#else
		} else {	
#endif
				resolved_basedir[resolved_basedir_len++] = PHP_DIR_SEPARATOR;
				resolved_basedir[resolved_basedir_len] = '\0';
		}
-- snip --
should work.

Under Windows, PHP_DIR_SEPARATOR is a backslash. So we check here if it is a forward slash.
 [2010-12-20 07:34 UTC] aharvey@php.net
-Status: Open +Status: Duplicate -Package: Security related +Package: Safe Mode/open_basedir
 [2010-12-20 07:34 UTC] aharvey@php.net
Duplicate of bug #53352.
 [2010-12-20 17:41 UTC] lekensteyn at gmail dot com
This is related to bug #53352 , but not an exact duplicate.

I've just added a patch on fopen_wrappers.c from the PHP 5.3 branch, r305698 ( http://svn.php.net/viewvc/php/php-src/branches/PHP_5_3/main/fopen_wrappers.c?view=markup&pathrev=305698 )
The patch fixed it for me.
 [2011-01-18 23:22 UTC] pajoye@php.net
Automatic comment from SVN on behalf of pajoye
Revision: http://svn.php.net/viewvc/?view=revision&amp;revision=307564
Log: - #53577 and cleanup
 [2011-01-18 23:30 UTC] pajoye@php.net
-Status: Duplicate +Status: Closed -Assigned To: +Assigned To: pajoye
 [2011-01-18 23:30 UTC] pajoye@php.net
fixed in revision 307563
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 11:01:29 2024 UTC