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: Analyzed Type: Bug Package: Safe Mode/open_basedir Operating System: Linux PHP Version: 5.2.13 New Comment: Please pay attention correct URL for debugging info is http://damore.xoom.it/apache-2.2_php-5.3.2_break-lstat.txt Previous Comments: ------------------------------------------------------------------------ [2010-07-13 21:04:24] v dot damore at gmail dot com If you take a look at debugging done in http://damore.xoom.it/apache-2.2_php-5.3.2_break-lstat.txt, you can see that tsrm_realpath_r is called in 2 different place: - First during phar_find_in_include_path function - Second during php_check_specific_open_basedir function. * During php_check_specific_open_basedir, traverse entire path at least three times, so i means 3 call to tsrm_realpath_r. I don't discuss the need to traverse entire path, but only one time. There should be a better way to implement such code, I'll try to write a patch if there is someone that want help me looking what I'm writing. ------------------------------------------------------------------------ [2010-07-13 15:23:33] paj...@php.net The reason was due to a security flaw involving symbolic links and realpath cache. It allowed to bypass open_basedir when a path was cached. The cleanest way to fix it was to disable the realpath cache when open_basedir/safemode are set. Thanks Johannes to remind us about this change. ------------------------------------------------------------------------ [2010-07-13 11:01:23] v dot damore at gmail dot com 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? ------------------------------------------------------------------------ [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 ------------------------------------------------------------------------ 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