2 votes

PHP Safe Mode/open_basedir - problème de performance de lstat

PHP lstat le chemin complet plusieurs fois avant de lire le fichier recherché. Et cela se produit lorsque dans la configuration apache httpd est spécifié PHP_ADMIN_VALUE paramètre open_basedir ou si safe_mode est ON .

Si j'ai un site web simple avec seulement la page phpinfo.php et à l'intérieur nous avons seulement "".

Considérons que nous avons la dernière version de httpd (2.2.15) et de PHP (5.2.13 ou 5.3.2).

Si nous spécifions safe_mode=on ou PHP_ADMIN_VALUE open_basedir dans Configuration de l'hôte virtuel :

<Directory "/usr/local/myspace/webspace/httpdocs">
                PHP\_ADMIN\_VALUE open\_basedir "/usr/local/myspace/webspace"
</Directory>
<VirtualHost \*:80>
        ServerName damorealt.xoom.it
        DocumentRoot "/usr/local/myspace/webspace/httpdocs"
    CustomLog   /var/log/httpd/damorealt/access\_log   combined
    ErrorLog   /var/log/httpd/damorealt/error\_log
</VirtualHost >

Page d'appel http://damorealt.xoom.it/phpinfo.php nous pouvons reproduire le comportement suivant :

Premier contrôle

25933 lstat("/usr", {st\_mode=S\_IFDIR|0755, st\_size=4096, ...}) = 0
25933 lstat("/usr/local", {st\_mode=S\_IFDIR|0755, st\_size=4096, ...}) = 0
25933 lstat("/usr/local/myspace", {st\_mode=S\_IFDIR|0755, st\_size=4096, ...}) = 0
25933 lstat("/usr/local/myspace/webspace", {st\_mode=S\_IFDIR|0755, st\_size=4096, ...}) = 0
25933 lstat("/usr/local/myspace/webspace/httpdocs", {st\_mode=S\_IFDIR|0755, st\_size=4096, ...}) = 0
25933 lstat("/usr/local/myspace/webspace/httpdocs/phpinfo.php", {st\_mode=S\_IFREG|0644, st\_size=16, ...}) = 0

Deuxième contrôle

25933 lstat("/usr", {st\_mode=S\_IFDIR|0755, st\_size=4096, ...}) = 0
25933 lstat("/usr/local", {st\_mode=S\_IFDIR|0755, st\_size=4096, ...}) = 0
25933 lstat("/usr/local/myspace", {st\_mode=S\_IFDIR|0755, st\_size=4096, ...}) = 0
25933 lstat("/usr/local/myspace/webspace", {st\_mode=S\_IFDIR|0755, st\_size=4096, ...}) = 0
25933 lstat("/usr/local/myspace/webspace/httpdocs", {st\_mode=S\_IFDIR|0755, st\_size=4096, ...}) = 0
25933 lstat("/usr/local/myspace/webspace/httpdocs/phpinfo.php", {st\_mode=S\_IFREG|0644, st\_size=16, ...}) = 0

Troisième contrôle (incomplet)

25933 lstat("/usr", {st\_mode=S\_IFDIR|0755, st\_size=4096, ...}) = 0
25933 lstat("/usr/local", {st\_mode=S\_IFDIR|0755, st\_size=4096, ...}) = 0
25933 lstat("/usr/local/myspace", {st\_mode=S\_IFDIR|0755, st\_size=4096, ...}) = 0
25933 lstat("/usr/local/myspace/webspace", {st\_mode=S\_IFDIR|0755, st\_size=4096, ...}) = 0

Cinquième contrôle.

25933 lstat("/usr", {st\_mode=S\_IFDIR|0755, st\_size=4096, ...}) = 0
25933 lstat("/usr/local", {st\_mode=S\_IFDIR|0755, st\_size=4096, ...}) = 0
25933 lstat("/usr/local/myspace", {st\_mode=S\_IFDIR|0755, st\_size=4096, ...}) = 0
25933 lstat("/usr/local/myspace/webspace", {st\_mode=S\_IFDIR|0755, st\_size=4096, ...}) = 0
25933 lstat("/usr/local/myspace/webspace/httpdocs", {st\_mode=S\_IFDIR|0755, st\_size=4096, ...}) = 0
25933 lstat("/usr/local/myspace/webspace/httpdocs/phpinfo.php", {st\_mode=S\_IFREG|0644, st\_size=16, ...}) = 0

Lisez le dossier !

25933 open("/usr/local/myspace/webspace/httpdocs/phpinfo.php", O\_RDONLY) = 16
25933 fstat(16, {st\_mode=S\_IFREG|0644, st\_size=16, ...}) = 0
25933 read(16, "\\n", 8192) = 16
25933 read(16, "", 8192)                = 0
25933 read(16, "", 8192)                = 0
25933 close(16)                         = 0

Si PHP_ADMIN_VALUE open_basedir "/usr/local/myspace/webspace" est supprimé : :

Premier contrôle

26235 time(NULL)                        = 1278696735
26235 lstat("/usr", {st\_mode=S\_IFDIR|0755, st\_size=4096, ...}) = 0
26235 lstat("/usr/local", {st\_mode=S\_IFDIR|0755, st\_size=4096, ...}) = 0
26235 lstat("/usr/local/myspace", {st\_mode=S\_IFDIR|0755, st\_size=4096, ...}) = 0
26235 lstat("/usr/local/myspace/webspace", {st\_mode=S\_IFDIR|0755, st\_size=4096, ...}) = 0
26235 lstat("/usr/local/myspace/webspace/httpdocs", {st\_mode=S\_IFDIR|0755, st\_size=4096, ...}) = 0
26235 lstat("/usr/local/myspace/webspace/httpdocs/phpinfo.php", {st\_mode=S\_IFREG|0644, st\_size=16, ...}) = 0

Lisez le fichier.

26235 open("/usr/local/myspace/webspace/httpdocs/phpinfo.php", O\_RDONLY) = 16
26235 fstat(16, {st\_mode=S\_IFREG|0644, st\_size=16, ...}) = 0
26235 read(16, "\\n", 8192) = 16
26235 read(16, "", 8192)                = 0
26235 read(16, "", 8192)                = 0
26235 close(16)                         = 0
26235 uname({sys="Linux", node="svilpar4", ...}) = 0
26235 time(NULL)                        = 1278696735
26235 writev(15, \[{"HTTP/1.1 200 OK\\r\\nDate: Fri, 09 J"..., 173},\[...\]
26235 chdir("/")                        = 0

Quelqu'un peut-il m'expliquer pourquoi PHP a un tel comportement ?

2voto

0x4a6f4672 Points 293

Le cache Realpath est désactivé si safe_mode ou open_basedir sont définis . Cela réduit considérablement les performances du moteur PHP et ce comportement peut mettre un serveur à genoux. Surtout parce qu'il y a un manque de documentation !

En regardant le code source main/main.c du moteur PHP 5.2.13, vous pouvez voir :

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;
        }

Veuillez vous référer à : http://bugs.php.net/bug.php?id=52312

0voto

Johannes Fuchs Points 1

Une solution de contournement est décrite ici : https://github.com/Whissi/realpath_turbo

avec cette extension vous pouvez utiliser realpatch cache avec openbasedir activé

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X