|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2007-06-27 13:17 UTC] ab5602@php.net
Description:
------------
When including files in directories that have access only permissions (no read or write), includes fail with a permission denied when trying things like
include ('../include_me.inc');
Directory permissions for the webserver process are access only (--x).
When including an absolute path, or relative path descending into the directory tree, include works ok eg:
include ('access_only/level2/include_me.inc');
The return value of "is_readable('../include_me.inc');" returns true, however include() fails.
Everything works find up to and including PHP 5.1.6, as of PHP 5.2.0 this problem occurs.
Anthony D. has access to our SPARC system and a test area in which this bug is reproduced has been set up. He should contact me at my work email address for further information.
Expected result:
----------------
The files should be included, as they were in versions prior to and in 5.1.6.
Actual result:
--------------
Warning: include(../include_me.inc) [function.include]: failed to open stream: Permission denied in /access_only/level2/index.php on line 15
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Fri Oct 24 08:00:01 2025 UTC |
Hi, the 'pwd' command works just fine for me too on any platform. However, suid'd use of the getcwd() function I think is the issue. The below demonstrates what I think is the going on with how Solaris behaves vs. how PHP expects the getcwd() command to behave. The following code was compiled and run on both Linux and Solaris platforms under a local filesystem and called cwdtest: #include <stdio.h> main() { char str[200]; if (getcwd(str, sizeof(str)) == NULL) printf("getcwd failed!!!\n"); else printf("CWD = %s\n",str); } ------ Linux ------ # uname -a Linux messaging2.wayne.edu 2.6.9-42.ELsmp #1 SMP Wed Jul 12 23:27:17 EDT 2006 i686 athlon i386 GNU/Linux # find ./localfs -ls 32001 8 d--x--x--x 3 nobody nobody 4096 Oct 1 13:05 ./localfs 32002 8 d--x--x--x 2 nobody nobody 4096 Oct 1 13:12 ./localfs/test123 32004 12 -rwsr-xr-x 1 nobody nobody 4878 Oct 1 13:06 ./localfs/test123/cwdtest # su nobody # cd /localfs/test123 # ./cwdtest CWD = /localfs/test123 # pwd /localfs/test123 # ------ Solaris 10 ------ # uname -a SunOS opteron 5.10 Generic_118855-14 i86pc i386 i86pc # find ./localfs -ls 449384 1 d--x--x--x 3 nobody nobody 512 Oct 1 13:13 ./localfs 449386 1 d--x--x--x 2 nobody nobody 512 Oct 1 13:13 ./localfs/test123 449388 7 -rwsr-xr-x 1 nobody nobody 6552 Oct 1 12:57 ./localfs/test123/cwdtest # su nobody # cd /localfs/test123 # ./cwdtest getcwd failed!!! # pwd /localfs/test123 #Wow, this is strange. I'm very much closer to seeing what is going on with PHP+Solaris that is causing the issue here Ian. I've tested pwd/getcwd() with every combination I could think of and this is how Solaris feels about permissions: If you are not root AND you want to get your current working directory that has parents with exclusively 'x' permissions, you must do one of two things: a) Execute a getuid() program that is suid-root. OR: And this is the strange one... b) Tell Solaris that you already know where you are!! If it is feasible, I'll see if I can come up with a patch to implement (b) if your architecture is Solaris and send it to the PHP internals list. See below for how this works: ----- # uname -a SunOS opteron 5.10 Generic_118855-14 i86pc i386 i86pc # pwd / # find ./dirtest/ -ls 449393 1 d--x--x--x 3 root root 512 Oct 1 19:29 ./dirtest/ 449394 1 d--x--x--x 2 root root 512 Oct 1 19:29 ./dirtest/dirtest2 # cd /dirtest/dirtest2 # pwd /dirtest/dirtest2 # su nobody # pwd cannot determine current directory # cd /dirtest/dirtest2/ # pwd /dirtest/dirtest2 #I created the following patch which fixes the problem, however it still needs discussion as to if it is a good way to implement this fix. At least it can serve as a starting point. One concern was if this should be implemented at a lower level (TSRM code). --- ./plain_wrapper.c.old 2007-10-05 02:50:59.000000000 -0400 +++ ./plain_wrapper.c 2007-10-05 02:55:38.000000000 -0400 @@ -885,9 +885,20 @@ return NULL; } - if ((realpath = expand_filepath(filename, NULL TSRMLS_CC)) == NULL) { - return NULL; - } + if ((realpath = expand_filepath(filename, NULL TSRMLS_CC)) == NULL) + { + if (options & STREAM_OPEN_FOR_INCLUDE) { + /* Attempt to open without path expansion anyways. + Files in Solaris dirs with --x will + not return a realpath, but are accessible */ + fd = open(filename, open_flags, 0666); + if (fd != -1) { + ret = php_stream_fopen_from_fd_int_rel(fd, mode, persistent_id); + return ret; } + else { + return NULL; } + } + } if (persistent) { spprintf(&persistent_id, 0, "streams_stdio_%d_%s", open_flags, realpath);