Bug #52312 [Com]: PHP lstat problem

From: Date: Tue, 13 Jul 2010 09:01:23 +0000
Subject: Bug #52312 [Com]: PHP lstat problem
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-152361@lists.php.net to get a copy of this message
Edit report at http://bugs.php.net/bug.php?id=52312&edit=1

 ID:               52312
 Comment by:       v dot damore at gmail dot com
 Reported by:      v dot damore at gmail dot com
 Summary:          PHP lstat problem
 Status:           Feedback
 Type:             Bug
 Package:          Safe Mode/open_basedir
 Operating System: Linux
 PHP Version:      5.2.13

 New Comment:

Looking at source code main/main.c of 5.2.13 I can see:

1292:		/* Disable realpath cache if safe_mode or open_basedir are set 
*/
                if (PG(safe_mode) || (PG(open_basedir) &&
*PG(open_basedir))) {
                        CWDG(realpath_cache_size_limit) = 0;
                }

1769:	/* Disable realpath cache if safe_mode or open_basedir are set */
        if (PG(safe_mode) || (PG(open_basedir) && *PG(open_basedir))) {
                CWDG(realpath_cache_size_limit) = 0;
        }

So realpath cache is definitely disabled in case of safe_mode or
open_basedir.
This dramatically reduce performance of PHP Engine and this behavior can
bring a 
server to its knees.
Especially because there is a lack of documentation!
Can you explain why this choose?
Must I continue debugging PHP engine in order to understand what's
happening?


Previous Comments:
------------------------------------------------------------------------
[2010-07-13 01:52:37] v dot damore at gmail dot com

I found where the problem is, this behavior is not a bug.
Looking at main/main.c I found following lines:

1416:           /* Disable realpath cache if safe_mode or open_basedir
are set */
                if (PG(safe_mode) || (PG(open_basedir) &&
*PG(open_basedir))) {
                        CWDG(realpath_cache_size_limit) = 0;
                }

1978:	/* Disable realpath cache if safe_mode or open_basedir are set */
        if (PG(safe_mode) || (PG(open_basedir) && *PG(open_basedir))) {
                CWDG(realpath_cache_size_limit) = 0;
        }

Could you explain why if safe_mode or open_basedir are set realpath
cache is disabled?

------------------------------------------------------------------------
[2010-07-13 01:38:26] v dot damore at gmail dot com

There is a interesting update, I have found CWDG define so now we have:

(gdb) print cwd_globals.realpath_cache_size_limit
$3 = 0

Probably you should check why realpath_cache_size_limit is equal to 0

------------------------------------------------------------------------
[2010-07-13 01:30:24] v dot damore at gmail dot com

After having set breakpoint tsrm_realpath_r and I have execute step by
step debug.
I think is interesting that after execution tsrm_virtual_cwd.c of line
681 execution continue on line 890.

gdb) break tsrm_realpath_r
Breakpoint 1 at 0x2b0b3c9f2702: file
/usr/local/sitipersonali/sitipersonali01/NSP_SERVICE/strillo/sources/php-5.3.2/TSRM/tsrm_virtual_cwd.c,
line 611.
(gdb) continue
Continuing.

Breakpoint 1, tsrm_realpath_r (path=0x7fffddfb32b0
"/usr/local/myspace/webspace/httpdocs/test.php", start=1, len=45,
ll=0x7fffddfb32ac, t=0x7fffddfb32a0, use_realpath=2, is_dir=0,
link_is_dir=0x0)
    at
/usr/local/sitipersonali/sitipersonali01/NSP_SERVICE/strillo/sources/php-5.3.2/TSRM/tsrm_virtual_cwd.c:611
611		int directory = 0;
(gdb) step
624			if (len <= start) {
(gdb) step
628			i = len;
(gdb) step
629			while (i > start && !IS_SLASH(path[i-1])) {
(gdb) step
630				i--;
(gdb) step
629			while (i > start && !IS_SLASH(path[i-1])) {
(gdb) step
630				i--;
(gdb) step
629			while (i > start && !IS_SLASH(path[i-1])) {
(gdb) step
630				i--;
(gdb) step
629			while (i > start && !IS_SLASH(path[i-1])) {
(gdb) step
630				i--;
(gdb) step
629			while (i > start && !IS_SLASH(path[i-1])) {
(gdb) step
630				i--;
(gdb) step
629			while (i > start && !IS_SLASH(path[i-1])) {
(gdb) step
630				i--;
(gdb) step
629			while (i > start && !IS_SLASH(path[i-1])) {
(gdb) step
630				i--;
(gdb) step
629			while (i > start && !IS_SLASH(path[i-1])) {
(gdb) step
630				i--;
(gdb) step
629			while (i > start && !IS_SLASH(path[i-1])) {
(gdb) step
633			if (i == len ||
(gdb) step
639			} else if (i == len - 2 && path[i] == '.' && path[i+1] ==
'.') {
(gdb) step
677			path[len] = 0;
(gdb) step
679			save = (use_realpath != CWD_EXPAND);
(gdb) step
681			if (start && save && CWDG(realpath_cache_size_limit)) {
(gdb) watch save
Hardware watchpoint 2: save
(gdb) print save
$1 = 1
(gdb) print start
$2 = 1
(gdb) print realpath_cache_size_limit
No symbol "realpath_cache_size_limit" in current context.
(gdb) step
890			if (save && lstat(path, &st) < 0) {
(gdb)

------------------------------------------------------------------------
[2010-07-13 00:59:44] rasmus@php.net

Set a bp and step through tsrm_realpath_r and figure out why it isn't
getting to 
the realptath_cache_find() call there.  Seems like it should be getting
there from 
the backtraces.

------------------------------------------------------------------------
[2010-07-13 00:52:21] v dot damore at gmail dot com

Please also note that realpath_cache_size and realpath_cache_ttl are
currently set to following values:

[root@svilpar4 ~]# curl http://damorealt.xoom.it/phpinfo.php | grep
real

<tr><td class="e">realpath_cache_size</td><td
class="v">1024k</td><td
class="v">1024k</td></tr>
<tr><td class="e">realpath_cache_ttl</td><td
class="v">600</td><td
class="v">600</td></tr>

------------------------------------------------------------------------


The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at

    http://bugs.php.net/bug.php?id=52312


-- 
Edit this bug report at http://bugs.php.net/bug.php?id=52312&edit=1


Thread (64 messages)

« previous php.bugs (#152361) next »