php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #40326 Can't open file from cwd if parent folder not readable
Submitted: 2007-02-02 15:22 UTC Modified: 2007-04-28 22:08 UTC
Votes:5
Avg. Score:4.6 ± 0.5
Reproduced:5 of 5 (100.0%)
Same Version:3 (60.0%)
Same OS:2 (40.0%)
From: sborrill at precedence dot co dot uk Assigned:
Status: Closed Package: Streams related
PHP Version: 5.2.0 OS: NetBSD 3.1_STABLE
Private report: No CVE-ID: None
 [2007-02-02 15:22 UTC] sborrill at precedence dot co dot uk
Description:
------------
With PHP versions prior to 5.2.0 (e.g. 5.1.6), you could fopen() a file in the current working directory (i.e. same as the script) even if a parent directory only had +x permission and not +rx for the webserver. With 5.2.0 (and today's 5.2 snapshot) you get "Warning: fopen(file) [function.fopen]: failed to open stream: No such file or directory [...]".

If it's of any relevance, with all versions, getcwd() returns FALSE on NetBSD if a parent folder is not readable, but this does not affect fopen().

This is affecting any user whose home area is mode 0711 when they run php from their public_html folder (which is mode 0755).

Reproduce code:
---------------
Ensuring ownership is not same as web server process (e.g. in public_html in user's home area):

mkdir one
mkdir one/two
chmod 711 one
chmod 755 one/two
echo "test" > one/two/testfile

one/two/index.php contains:
<?php
echo "cwd:".getcwd()."<br>";
$fp=fopen("testfile","r");
if($fp) fpassthru($fp);
?>

Stage one:
chmod 711 one

Stage two:
chmod 755 one

Expected result:
----------------
(stage one):
cwd:
test

(stage two)
cwd: /home/testuser/public_html
test



Actual result:
--------------
(stage 1):
cwd:
Warning: fopen(file) [function.fopen]: failed to open stream: No such file or directory [...]

(stage two)
cwd: /home/testuser/public_html
test



Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2007-02-02 18:44 UTC] tony2001@php.net
Cannot reproduce.
Both PHP 5.2-CVS and PHP 6-CVS work just fine with Apache 1.x.

 [2007-02-03 09:32 UTC] sborrill at precedence dot co dot uk
What OS? Are you sure you've checked file ownership? What do you get on the getcwd() lines?

We are finding this is 100% reproducible on all our customers' servers when they are using php in a UserDir.

I've checked the package definition and patches at:
http://cvsweb.netbsd.org/bsdweb.cgi/pkgsrc/lang/php5/
Nothing relevant has been altered betweeen 5.1.6 and 5.2.0 in the NetBSD pkg.

php.ini file remains the same throughout. We aren't using safe mode or open_basedir. I looked at the CVS log for fopen_wrapper.c but didn't spot anything relevant. I'm not familiar enough with PHP internals to know where to add much debugging, but I'm happy to follow any suggestions.
 [2007-02-05 09:40 UTC] tony2001@php.net
>What OS? 
Linux

>Are you sure you've checked file ownership? 
#ls -ld /www
d--x--x--x  15 tony users 2864 Feb  5 12:36 /www
#ls -l /www/index.php
-rw-r--r--  1 tony users 110 Feb  5 12:36 /www/index.php

Apache runs as user "wwwrun".

>What do you get on the getcwd() lines?
string(4) "/www"

Please try the latest snapshot from http://snaps.php.net if you're using some patches/adopted version.
 [2007-02-05 13:45 UTC] sborrill at precedence dot co dot uk
OK, permissions are nearly the same (except in our case, it's the parent of the www directory that is -r not the www itself, but that's probably unimportant).

The getcwd() line shows a difference though. On NetBSD and other Unix OSes (all except for Linux?) getcwd() returns FALSE as noted in http://bugs.php.net/bug.php?id=24185

Perhaps the reason it's working for you on Linux is because your getcwd() _isn't_ returning FALSE and there's now an extra getcwd() call in the fopen codepath. N.B. as in my original report, with PHP 5.1.6, getcwd() returned FALSE, but fopen worked nonetheless.

Also, the patches to PHP in the NetBSD package are the same between 5.1.6 and 5.2.0 (or if they differ it's in an unrelated section). The patches related to php.ini, configure, curl and imap/c-client only. Everything else is stock:

http://cvsweb.netbsd.org/bsdweb.cgi/pkgsrc/lang/php5/patches/
 [2007-02-05 13:51 UTC] tony2001@php.net
Please try using this CVS snapshot:

  http://snaps.php.net/php5.2-latest.tar.gz
 
For Windows:
 
  http://snaps.php.net/win32/php5.2-win32-latest.zip


 [2007-02-10 19:25 UTC] sborrill at precedence dot co dot uk
Yes, as per my original bug report, it is not fixed in the daily snapshots. I've confirmed it today's too.

I can recreate it with the cli php binary too (i.e. I don't have to test it from Apache).
 [2007-02-10 21:39 UTC] sborrill at precedence dot co dot uk
I've tracked this down to changes to virtual_file_ex() which is called from expand_filepath(). expand_filepath() returns "/file" from "file" with 5.2.0 (and later), but returns "file" with 5.1.6 and earlier. This is down to changes between revisions 1.74.2.9 (v5.1.6) and 1.74.2.9.2.9 (v5.2.0) of TSRM/tsrm_virtual_cwd.c. I've not yet tracked it down further.
 [2007-02-12 17:49 UTC] tony2001@php.net
Please provide an account on this machine.
 [2007-02-20 01:00 UTC] php-bugs at lists dot php dot net
No feedback was provided for this bug for over a week, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".
 [2007-02-23 09:47 UTC] tlaramie at superb dot net
I can replicate the issue verbatim on PHP 5.2.1 on Solaris 9 (SPARC). Login information for testing by one of the developers is available per their request.
 [2007-02-23 11:51 UTC] sborrill at precedence dot co dot uk
What sort of account? FTP/ssh/something else? Alternatively, big thanks to tlaramie at superb dot net for offering a suitable account.

The error was introduced in revision 1.74.2.9.2.4 and is around line 584 for TSRM/tsrm_virtual_cwd.c in the loop that begins:
ptr = tsrm_strtok_r(path_copy, TOKENIZER_STRING, &tok);

This loop is not run in 1.74.2.9.2.3 if the cwdlen is 0. With 1.74.2.9.2.4 and later it is always run and so prepends a / on the file name, i.e. the actual file that is opened with fopen("file","r") is "/file". This strikes me as a potential security problem too.
 [2007-02-27 21:55 UTC] lthomas at cs dot umn dot edu
"[3 Feb 9:32am UTC] sborrill at precedence dot co dot uk" suggested that this is 100% reproducible when using PHP within UserDir.  I've encountered the bug both within and without UserDir.

With UserDir:
Apache 2.2.4 & PHP 5.2.1 in Solaris 8

Without UserDir:
Apache 2.0.59 & PHP 5.2.1 in Solaris 8
 [2007-04-26 09:26 UTC] tony2001@php.net
Please try using this CVS snapshot:

  http://snaps.php.net/php5.2-latest.tar.gz
 
For Windows:
 
  http://snaps.php.net/win32/php5.2-win32-latest.zip


 [2007-04-28 22:08 UTC] sborrill at precedence dot co dot uk
Fix to tsrm_virtual_cwd.c fixes problem.

Thanks.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 21 11:01:30 2024 UTC