php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #51860 Include fails with toplevel symlink to /
Submitted: 2010-05-19 16:46 UTC Modified: 2012-01-30 10:52 UTC
Votes:31
Avg. Score:4.9 ± 0.4
Reproduced:14 of 17 (82.4%)
Same Version:13 (92.9%)
Same OS:10 (71.4%)
From: stephan dot suerken at 1und1 dot de Assigned: dmitry
Status: Closed Package: Scripting Engine problem
PHP Version: 5.3.2 OS:
Private report: No CVE-ID:
 [2010-05-19 16:46 UTC] stephan dot suerken at 1und1 dot de
Description:
------------
Tarball: http://stephan-suerken.de/tmp/php53include.tar.gz

Hi,

with a certain directory setup (symlink pointing to /, see file tree in php53include.tar.gz) plus script call syntax (see scripts "ok" and "fail" scripts in tarball), including a file meekly fails.

I have not completely debugged it, but afaics "php_resolve_path" fails were it should not; I suspect some of the "canonize path" functions wrongly give an error here.

Thanks,

Stephan

Test script:
---------------
Steps to reproduce:

1. Download: http://stephan-suerken.de/tmp/php53include.tar.gz
[as root]
2. cd /
3. tar xfz php53include.tar.gz
4. /phptest/fail


Expected result:
----------------
# manwe(CHROOT:sid-ui): /phptest
# root? ./ok 
/phpinclude/inc123.php: OK, INCLUDED



Actual result:
--------------
# manwe(CHROOT:sid-ui): /phptest
# root? ./fail
PHP Warning:  require(/phplink/phpinclude/inc123.php): failed to open stream: No such file or directory in /phptest/test.php on line 2
PHP Fatal error:  require(): Failed opening required '/phplink/phpinclude/inc123.php' (include_path='.:/usr/share/php:/usr/share/pear') in /phptest/test.php on line 2



Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-05-20 14:14 UTC] mike@php.net
You think anybody's goind to untar something in his root AS root?
Please provide some proper steps to reproduce, thank you.
 [2010-05-20 14:14 UTC] mike@php.net
-Status: Open +Status: Feedback
 [2010-05-21 12:06 UTC] thekid@php.net
1) Create a symlink in / to /
root@thekid:/ > ln -s / phptest
root@thekid:/ > ls -al /phptest
lrwxr-xr-x  1 root  wheel  1 May 21 10:40 /phptest -> /

2) Verify
root@thekid:/ > echo "OK" > /phpfile
root@thekid:/ > php -r 'include("/phptest/phpfile");'

Expected result: "OK"

3) Clean up
root@thekid:/ > rm /phptest /phpfile

You need to be root because you're working in /, that's it:)
 [2010-05-21 13:05 UTC] stephan dot suerken at 1und1 dot de
-Status: Feedback +Status: Open
 [2010-05-21 13:05 UTC] stephan dot suerken at 1und1 dot de
>[2010-05-20 10:14 UTC] mike@php.net

>You think anybody's goind to untar something in his root AS root?

Well...yes ;). Look at the tarball first, it's harmless.

>Please provide some proper steps to reproduce, thank you.

I could not find another way to reproduce it (yet) but in /; the tarball seems to be the easiest way to make someone else reproduce it.

Thx,

Stephan
 [2010-05-21 13:12 UTC] thekid@php.net
Cannot reproduce on Gentoo with 5.3.2-RELEASE.
 [2010-05-21 13:37 UTC] thekid@php.net
Wait:

# /opt/php/php-5.3.2/sapi/cli/php -r 'var_dump(realpath("/phplink/phpinclude/inc123.php"));' 
string(22) "/phpinclude/inc123.php"

...and:
# echo '<?php var_dump(realpath("/phplink/phpinclude/inc123.php"));' > test.php
# /opt/php/php-5.3.2/sapi/cli/php test.php
string(22) "/phpinclude/inc123.php"

But:
# echo '<?php var_dump(realpath("/phplink/phpinclude/inc123.php"));' > /phplink/phptest/test.php
# /opt/php/php-5.3.2/sapi/cli/php /phplink/phptest/test.php  
bool(false)

So if the executed script itself is inside the symlink'd directory, VCWD_REALPATH() does not correctly work (used by both include / require and realpath(), that's why I'm using the latter here)

This does not occur with PHP 5.2.X (or PHP4, btw)
 [2010-05-21 13:44 UTC] stephan dot suerken at 1und1 dot de
> [2010-05-21 09:12 UTC] thekid@php.net 

Your "simplified" way does not produce the bug; did you do it with the exact settings in the tarball (really, it does not harm!)? Thing is, the slightest change in the "setup" make the bug go away, and the exact setup described in the tarball reproduces it.

For what I know, you _need_ the extra include dir under / to reproduce, and you _must_ call php as described in the "fail" script in the tarball, i.e. with the full path _including_ the symlink. Both is not in your simplified way to reproduce it.

Thanks!

Stephan
 [2010-05-21 13:58 UTC] thekid@php.net
-Status: Open +Status: Analyzed
 [2010-05-21 13:58 UTC] thekid@php.net
Here's the simplest way to reproduce:

xpsrv / # ln -s / phptest
xpsrv / # echo "OK" > /phpfile
xpsrv / # echo '<?php include("/phptest/phpfile");' > /phpinc

Works:
xpsrv / # php532 /phpinc
OK

Breaks:
xpsrv / # php532 /phptest/phpinc
Warning: include(/phptest/phpfile): failed to open stream: No such file or directory in /phpinc on line 1
Warning: include(): Failed opening '/phptest/phpfile' for inclusion (include_path='.:') in /phpinc on line 1

xpsrv / # php532 -v | head -1
PHP 5.3.2 (cli) (built: May 21 2010 12:18:37)
 [2010-05-21 14:04 UTC] stephan dot suerken at 1und1 dot de
-Status: Analyzed +Status: Open
 [2010-05-21 14:04 UTC] stephan dot suerken at 1und1 dot de
> [2010-05-21 09:37 UTC] thekid@php.net

> Wait:

> So if the executed script itself is inside the symlink'd directory, 
> VCWD_REALPATH() does not correctly work (used by both include / require and
> realpath(), that's why I'm using the latter here)

Great, thanks, that sounds much like what I expected ;).

If it might be helpful, I already stepped through the code with gdb (breaking in some top level *resolve_path (cant remeber exaytly right now) function ), finding the bug does _not_ occur then; maybe this hints to some strange race condition.

Thx,

Stephan
 [2010-05-30 01:05 UTC] felipe@php.net
-Package: Reproducible crash +Package: Scripting Engine problem
 [2010-06-27 12:26 UTC] rainer at hosting-ist-mein-leben dot de
Hi,

we got this problem too. We need a fix for this. Plz. thx.

cu
Rainer
 [2010-08-13 17:08 UTC] rainer at hosting-ist-mein-leben dot de
Problem also in the new version (5.3.3)
 [2011-01-12 17:46 UTC] rainer at hosting-ist-mein-leben dot de
Problem also in the new version (5.3.3)
 [2011-01-12 17:47 UTC] rainer at hosting-ist-mein-leben dot de
I mean 5.3.5
 [2011-01-21 10:34 UTC] plubber at gmx dot ch
no solution?

I have the same problem with mounted NFS
 [2011-07-06 10:36 UTC] rainer at hosting-ist-mein-leben dot de
In latest 5.4.0-alpha1 problem is still there.
 [2012-01-17 14:51 UTC] startup09 at web dot de
please fix this! 1&1 still uses 5.2 for all customers because of this bug.
I'm one of these poor people and can't use newer extensions which require 5.3 :(
 [2012-01-28 13:39 UTC] grobmeier at gmail dot com
I can only agree with startup09. Please fix it. Thousands 1&1 (among others) 
customers are using old PHP because of this one. It is going to have birthday 
soon. I cannot upgrade my Open Source projects because 5.2 ist sill used on so 
many hosts. You need to get this done if you really have an interest your users 
migrate to 5.3.
 [2012-01-28 18:44 UTC] rasmus@php.net
-Status: Open +Status: Feedback
 [2012-01-28 18:44 UTC] rasmus@php.net
I am unable to reproduce this with current PHP versions.

Here is what I did:

% cd /
% ln -s / phptest
% echo "OK" > /phpfile
% echo '<?php include "/phptest/phpfile";' > /phpinc

% /home/rasmus/php-src/branches/PHP_5_4/sapi/cli/php phpinc
OK

% /home/rasmus/php-src/branches/PHP_5_3/sapi/cli/php phpinc
OK

% php phpinc
OK

% cd /phptest
% php phpinc
OK

What am I missing? This seems to be exactly the setup that thekid described.
 [2012-01-28 18:48 UTC] rasmus@php.net
Never mind, I see it now.

% php phptest/phpinc
OK

But

% php /phptest/phpinc

Warning: include(/phptest/phpfile): failed to open stream: No such file or 
directory in /phpinc on line 2

Warning: include(): Failed opening '/phptest/phpfile' for inclusion 
(include_path='.:/usr/local/lib/php') in /phpinc on line 2
 [2012-01-28 21:11 UTC] rasmus@php.net
It turns out that this is a bug in the realpath cache implementation we added in 
5.3. An inefficient workaround is to set realpath_cache_size=0 in your php.ini, 
That fixes the issue, but you take a performance hit in terms of extra lstat 
calls.

Still working on a simple fix that doesn't break everything for this one.
 [2012-01-28 21:11 UTC] rasmus@php.net
-Status: Feedback +Status: Open
 [2012-01-30 08:05 UTC] dmitry@php.net
-Assigned To: +Assigned To: dmitry
 [2012-01-30 10:08 UTC] dmitry@php.net
Automatic comment from SVN on behalf of dmitry
Revision: http://svn.php.net/viewvc/?view=revision&amp;revision=322927
Log: Fixed bug #51860 (Include fails with toplevel symlink to /)
 [2012-01-30 10:52 UTC] dmitry@php.net
-Status: Assigned +Status: Closed
 [2012-01-30 10:52 UTC] dmitry@php.net
This bug has been fixed in SVN.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.

 For Windows:

http://windows.php.net/snapshots/
 
Thank you for the report, and for helping us make PHP better.


 [2012-04-18 09:46 UTC] laruence@php.net
Automatic comment on behalf of dmitry
Revision: http://git.php.net/?p=php-src.git;a=commit;h=0d32d361e63193b09051c4cb285df1ed015d91b7
Log: Fixed bug #51860 (Include fails with toplevel symlink to /)
 [2012-07-24 23:37 UTC] rasmus@php.net
Automatic comment on behalf of dmitry
Revision: http://git.php.net/?p=php-src.git;a=commit;h=0d32d361e63193b09051c4cb285df1ed015d91b7
Log: Fixed bug #51860 (Include fails with toplevel symlink to /)
 [2013-11-17 09:34 UTC] laruence@php.net
Automatic comment on behalf of dmitry
Revision: http://git.php.net/?p=php-src.git;a=commit;h=0d32d361e63193b09051c4cb285df1ed015d91b7
Log: Fixed bug #51860 (Include fails with toplevel symlink to /)
 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Sun Apr 20 21:01:56 2014 UTC