php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #68587 auto_prepend_file breaks Apache2 virtual hosts if same contents
Submitted: 2014-12-11 02:03 UTC Modified: 2014-12-11 06:26 UTC
From: dante at lorenso dot com Assigned:
Status: Not a bug Package: Apache2 related
PHP Version: 5.5.19 OS: Ubuntu 14.04 LTS
Private report: No CVE-ID: None
 [2014-12-11 02:03 UTC] dante at lorenso dot com
Description:
------------
Given 2 different virtual hosts in Apache, if auto_prepend_file is used in both virtual hosts and the files contain the exact same data, the first virtual host loaded by Apache is used for all subsequent virtual hosts.

Example ...

<VirtualHost...>
php_value auto_prepend_file bootstrap.php
</VirtualHost>

<VirtualHost...>
php_value auto_prepend_file bootstrap.php
</VirtualHost>

Changing contents of just one of the bootstrap.php files to alter the contents will correct the problem and allow Apache to serve different virtual host DocumentRoot content.

Expected result:
----------------
php_value auto_prepend_file bootstrap.php should be independent of file contents and should be defined separately for each virtual host without conflict.


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2014-12-11 02:18 UTC] requinix@php.net
-Status: Open +Status: Feedback
 [2014-12-11 02:18 UTC] requinix@php.net
Thank you for this bug report. To properly diagnose the problem, we
need a short but complete example script to be able to reproduce
this bug ourselves. 

A proper reproducing script starts with <?php and ends with ?>,
is max. 10-20 lines long and does not require any external 
resources such as databases, etc. If the script requires a 
database to demonstrate the issue, please make sure it creates 
all necessary tables, stored procedures etc.

Please avoid embedding huge scripts into the report.

bootstrap.php, specifically. Do you happen to be using that to effectively "load" the website? Could it be confused about which site it's supposed to load?
Exactly what did you change to make the problem go away?

Because I can tell you this: Apache is not looking for the php_value directive that defines auto_prepend_file, examining the referenced file, deciding that since the contents of the file matches those of a previous VirtualHost's the two sites are the same, and disregarding all other configuration directives such as ServerName/Alias and DocumentRoot which may contradict that conclusion.
 [2014-12-11 04:28 UTC] dante at lorenso dot com
-Status: Feedback +Status: Open
 [2014-12-11 04:28 UTC] dante at lorenso dot com
I added the following code to BOTH bootstrap.php files ...

  error_log(str_repeat('-', 80));
  error_log('FILE: ' . __FILE__);
  error_log('DIR: ' . __DIR__);
  error_log('ROOT_DIR: ' . ROOT_DIR);
  $files = get_included_files();
  edump($files);

And here are the 2 outputs ...

After loading the first virtual host URL(keydb):

[Wed Dec 10 22:16:22.146732 2014] [:error] [pid 18058] [client 10.0.8.2:6687] FILE: /www/prod/keydb/public/bootstrap.php
[Wed Dec 10 22:16:22.146840 2014] [:error] [pid 18058] [client 10.0.8.2:6687] DIR: /www/prod/keydb/public
[Wed Dec 10 22:16:22.146926 2014] [:error] [pid 18058] [client 10.0.8.2:6687] ROOT_DIR: /www/prod/keydb
[Wed Dec 10 22:16:22.147380 2014] [:error] [pid 18058] [client 10.0.8.2:6687] [01] Array\n(\n    [0] => /www/prod/keydb/public/bootstrap.php\n)\n

And after loading the second virtual host URL(acd):

[Wed Dec 10 22:16:29.082052 2014] [:error] [pid 18056] [client 10.0.8.2:43767] FILE: /www/prod/keydb/public/bootstrap.php
[Wed Dec 10 22:16:29.082153 2014] [:error] [pid 18056] [client 10.0.8.2:43767] DIR: /www/prod/keydb/public
[Wed Dec 10 22:16:29.082236 2014] [:error] [pid 18056] [client 10.0.8.2:43767] ROOT_DIR: /www/prod/keydb
[Wed Dec 10 22:16:29.082461 2014] [:error] [pid 18056] [client 10.0.8.2:43767] [01] Array\n(\n    [0] => /www/dev/acd/public/bootstrap.php\n)\n

NOTICE how loading the "acd" project ... in the get_included_files() array it lists the file name as /www/dev/acd/public/bootstrap.php?  But, the value of __FILE__ lists a DIFFERENT file ... the one from the other virtual host: /www/prod/keydb/public/bootstrap.php.

I agree now that this is not affecting the Apache 2 virtual hosts directly, but it IS a bug inside PHP somewhere.  PHP is confused about which file it is actually parsing because 

  get_included_files()[0] != __FILE__

For the auto_prepend_file declared in each virtual host.  In my projects, it is not the same virtual host that is used, but it IS the same bootstrap.php file being used, so PHP sets all the define constants to values based on the bootstrap.php file:

  define('ROOT_DIR', realpath(__DIR__ . '/..'));

And this triggers the SPL auto loader to use the wrong classes:

  // PSR-4: convert class name to file name
  $lib_file = ROOT_DIR . '/library/' . strtr(ltrim($class_name, '\\'), array('\\' => '/')) . '.php';
  if (file_exists($lib_file)) {
      include $lib_file;
      return true;
  }

Which effectively makes all the asset files and library classes load from the wrong site.

-- Dante
 [2014-12-11 04:47 UTC] requinix@php.net
-Status: Open +Status: Feedback
 [2014-12-11 04:47 UTC] requinix@php.net
Using OPcache? What's the value of opcache.use_cwd? If off, does turning it on fix the problem?
 [2014-12-11 04:57 UTC] dante at lorenso dot com
-Status: Feedback +Status: Open
 [2014-12-11 04:57 UTC] dante at lorenso dot com
Problem resolved by disabling XCache.  On Ubuntu 14.04 LTS, the following command was run:

  > php5dismod xcache

Then apache2 was restarted, and the problem has gone away.  The proper auto_prepend_file is being loaded from the virtual host now.

To confirm, I run the following command:

  > php5enmod xcache

and restart apache.  The problem returns.  

So, for now, I will leave XCache disabled.

-- Dante
 [2014-12-11 05:35 UTC] requinix@php.net
-Status: Open +Status: Not a bug
 [2014-12-11 05:35 UTC] requinix@php.net
According to
  http://xcache.lighttpd.net/ticket/291
  http://xcache.lighttpd.net/ticket/296
this problem shouldn't exist in 3.1, which Ubuntu 14.04 and the ondrej PPA have.
As per comment 18 on ticket 296, ReadonlyProtection
  http://xcache.lighttpd.net/wiki/ReadonlyProtection
may help, and/or setting xcache.mmap_path to two different locations.
  http://xcache.lighttpd.net/wiki/XcacheIni#XCacheCacher

Unfortunately I don't know enough about XCache to offer more than that.
 [2014-12-11 05:39 UTC] dante at lorenso dot com
-Status: Not a bug +Status: Open
 [2014-12-11 05:39 UTC] dante at lorenso dot com
The OPcache is turned on ... but I don't think this is the problem.

  opcache.use_cwd	On	On

This problem is fixed by turning OFF XCache but leaving OPcache unchanged.  I tried some attempts to modify the XCache namespace, but this DID NOT WORK:

  <VirtualHost...>
  php_admin_value xcache.var_namespace acd
  php_value auto_prepend_file /www/dev/acd/public/bootstrap.php
  </VirtualHost>

  <VirtualHost...>
  php_admin_value xcache.var_namespace keydb
  php_value auto_prepend_file /www/prod/keydb/public/bootstrap.php
  </VirtualHost>

I don't think the var_namespace affected XCache's knowledge of the original file path.  And like I said, changing the contents of the bootstrap.php so that each virtual host had DIFFERENT data did work.  Unfortunately, in these two projects, I'm using the same bootstrap.php from source control and do not want to force them to be different just to work around the XCache bug.

-- Dante
 [2014-12-11 05:55 UTC] dante at lorenso dot com
Default Ubuntu 14.04 xcache settings are in use ... here is the default configuration:

> php -i | grep -i xcache

/etc/php5/cli/conf.d/20-xcache.ini,
    with XCache v3.1.0, Copyright (c) 2005-2013, by mOo
    with XCache Optimizer v3.1.0, Copyright (c) 2005-2013, by mOo
    with XCache Cacher v3.1.0, Copyright (c) 2005-2013, by mOo
    with XCache Coverager v3.1.0, Copyright (c) 2005-2013, by mOo
XCache
XCache Version => 3.1.0
xcache.coredump_directory => no value => no value
xcache.disable_on_crash => Off => Off
xcache.experimental => Off => Off
xcache.test => Off => Off
XCache Cacher
XCache Cacher Module => enabled
xcache.admin.enable_auth => On => On
xcache.allocator => bestfit => bestfit
xcache.cacher => On => On
xcache.count => 1 => 1
xcache.gc_interval => 0 => 0
xcache.mmap_path => /dev/zero => /dev/zero
xcache.readonly_protection => Off => Off
xcache.shm_scheme => mmap => mmap
xcache.size => 60M => 60M
xcache.slots => 8K => 8K
xcache.stat => On => On
xcache.ttl => 0 => 0
xcache.var_allocator => bestfit => bestfit
xcache.var_count => 1 => 1
xcache.var_gc_interval => 300 => 300
xcache.var_maxttl => 0 => 0
xcache.var_namespace => cheese => cheese
xcache.var_namespace_mode => 1 => 1
xcache.var_size => 4M => 4M
xcache.var_slots => 8K => 8K
xcache.var_ttl => 0 => 0
XCache Coverager
XCache Coverager Module => enabled
xcache.coveragedump_directory => no value => no value
xcache.coverager => Off => Off
xcache.coverager_autostart => On => On
XCache Optimizer
XCache Optimizer Module => enabled
xcache.optimizer => Off => Off

I will play more with some of these settings to see if I can re-enable XCache to work around the problem.
 [2014-12-11 06:18 UTC] dante at lorenso dot com
No success :\  These setting also DID NOT work...

  php_admin_value xcache.readonly_protection On
  php_admin_value xcache.mmap_path /tmp/xcache1
  php_value auto_prepend_file /www/prod/keydb/public/bootstrap.php

I'm wondering if those tickets:

  http://xcache.lighttpd.net/ticket/291
  http://xcache.lighttpd.net/ticket/296

Might have been referencing other bugs and maybe the auto_prepend_file is a special case of cache loading that wasn't addressed?

Unless I can turn XCache ON and not have this problem, it is still a BUG.  I can work around the bug by turning XCache OFF, but that shouldn't be the right answer.

-- Dante
 [2014-12-11 06:26 UTC] requinix@php.net
-Status: Open +Status: Not a bug
 [2014-12-11 06:26 UTC] requinix@php.net
This may very well be a bug, and I'll agree it certainly seems that way, but it's with XCache. So this report is not a bug - as in not a bug with PHP.
You need to go over to the XCache site and create a report on *their* bug tracking system.
 
PHP Copyright © 2001-2022 The PHP Group
All rights reserved.
Last updated: Fri Dec 02 21:04:48 2022 UTC