php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #58530 Joomla 1.5 instances corrupt cache
Submitted: 2009-01-30 00:52 UTC Modified: 2016-08-31 15:12 UTC
Votes:2
Avg. Score:4.0 ± 1.0
Reproduced:2 of 2 (100.0%)
Same Version:2 (100.0%)
Same OS:2 (100.0%)
From: gizmo at aoaforums dot com Assigned: cmb (profile)
Status: Wont fix Package: APC (PECL)
PHP Version: 5.2.5 OS: Linux
Private report: No CVE-ID: None
 [2009-01-30 00:52 UTC] gizmo at aoaforums dot com
Description:
------------
I'm currently running a Gentoo server with the 2007.0 profile, and the hardened sources, on kernel 2.6.27-r13.  I have PHP 5.2.8-r1 and Suhosin 0.9.27, with Apache 2.2.10 and MySQL 5.0.70-r1.

I have installed 3.0.19 of APC, and two instances in completely different directories, of Joomla 1.5.8.  Each Joomla instance has its own database.

(All packages have been installed using Gentoo Portage, or PECL in the case of APC).

When I have APC enabled, one of the Joomla instances will start using data from the other Joomla instance.  It appears that when Joomla starts up, it is requesting the configuration.php file from its local directory, and actually getting the contents of the file from the OTHER directory.  Turning APC off causes things to function normally.

I haven't yet determined if the first site to get cached is the one that always gets returned, or if it is totally random.

For what it's worth, I had the exact same problem with eAccelerator.  The problem appears to only affect Joomla 1.5.

Reproduce code:
---------------
settings from /etc/apc.ini

extension=apc.so
apc.enabled="0"
apc.shm_segments="6"
apc.shm_size="16"
apc.user_entries_hint="1024"
apc.num_files_hint="1024"
apc.ttl="1800"
apc.user_ttl="1800"
apc.gc_ttl="900"
apc.cache_by_default="1"
;apc.filters=""
;apc.mmap_file_mask="/tmp/apcphp5.XXXXXX"
apc.slam_defense="0"
apc.file_update_protection="2"
apc.enable_cli="0"
apc.max_file_size="1M"
apc.stat="1"
apc.write_lock="1"
apc.report_autofilter="0"
apc.include_once_override="0"
apc.rfc1867="0"
apc.rfc1867_prefix="upload_"
apc.rfc1867_name="APC_UPLOAD_PROGRESS"
apc.rfc1867_freq="0"
apc.localcache="0"
apc.localcache.size="512"
apc.coredump_unmap="0"


Expected result:
----------------
Sites should not share scripts via the cache unexpectedly.

Actual result:
--------------
Sites appear to share some cached php scripts, with unexpected results.

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-02-01 20:53 UTC] gopalv82 at yahoo dot com
Please put up the apc.php that came with your apc install into the docroot and hit it.

Possibly, joomla is using apc cache and both instances are hitting the cache with the same key. More like

if(!($data = apc_fetch('foo'))) { include("foo.php"); }

perhaps - please check for it. I'm pondering on a 
apc.vhost_mask feature to allow the same code to be run in
different vhosts without issues.
 [2009-02-01 22:14 UTC] gizmo at aoaforums dot com
By golly, you're right.  It never even crossed my mind that Joomla might have code to take advantage of APC.  The only place that specifically uses APC is Joomla 1.5's built-in cache handler, and I've got it turned off.  However, it would appear there is still something going on, because the first site to be hit gets cached, while the second site uses the first site's cached info (no evidence of the second site in the cached files output from apc.php).

I have multiple installs of Joomla 1.0 on this site, and they are unaffected.  The same is true of the multiple installs of vBulletin.  Now that I've some idea of what's happening, I'll open an issue with the Joomla 1.5 team.

Sorry to have troubled you for this when it wasn't your problem.
 [2009-02-03 23:38 UTC] gopalv82 at yahoo dot com
well, try this to an apache pid 

sudo gdb

(gdb) attach <pid>

(gdb) break zif_apc_fetch
(gdb) commands
 p executor_globals.current_execute_data->prev_execute_data->function_state.function->op_array.function_name
c
end
(gdb) continue

gdb will break whenever you hit apc_fetch and let you 
figure out what key it is inserting of sorts. That long 
line after p is the way to figure out the previous function
in the call trace.

Hit that apache with enough hits until you get lucky
and hit the pid you are attached to. Perhaps there's
some joomla extension/library that uses this ?
 [2009-02-05 22:57 UTC] gizmo at aoaforums dot com
I'll be trying it this weekend, and I'll post back with the results.
 [2009-02-15 08:58 UTC] gizmo at aoaforums dot com
I've tried this, but either I'm doing something wrong or I'm colossally unlucky, or this function is never being called, because I never got the break-point, despite several tens of thousands of page requests (I set up an instance of wget to request the home page of the site and just let it loop).  Probably I'll have to modify the Joomla source with some tracing logic to see what is going on.
 [2009-02-15 18:45 UTC] gizmo at aoaforums dot com
I finally figured out what was going on here.

See, under Gentoo, we've got a configuration manager called webapp-config, which is used to install web applications like Joomla and AWSTATS.

webapp-config works by taking files from a central repository and copying them to the specified server (apache VHOST) directory.  It will make physical copies of the files if necessary, but prefers to make hard links, ala the ln command.

If I understand things correctly, a hard-link'd file is nothing more than a file-system pointer to the inode, meaning that only one physical copy of the file exists, but it appears two places in the directory tree.  That would mean that from APC's perspective, both file system entries are the same (because they in fact ARE the same file), and thus APC would serve up the first cached copy of the file.

In short, this is neither a Joomla problem nor an APC problem, but a configuration error caused by not understanding what the tool in question was doing.
 [2009-02-15 22:51 UTC] gizmo at aoaforums dot com
Some more information on this, if you want to pursue.  I'm not sure if you want to consider this a bug or not, but it is certainly a situation where APC behaves differently from plain PHP.

Save the following code in a web-accessible directory somewhere as e.g. /var/www/www.testserver.org/htdocs/cachetest.php:

<?php
    echo dirname(__FILE__);
?>

now, make a hardlink to this file from some other directory like so:

ln cachetest.php /var/www/www.othertestserver.org/htdocs

Hit the first file with a browser, and observe the output, which should be:

/var/www/www.testserver.org/htdocs

Now, hit the second file with the web browser, and observe the output, which WE EXPECT TO be:

/var/www/www.othertestserver.org/htdocs

In fact, however, the output will be identical to the output from the first file.

Disable APC, and the output will be what we expect.  With APC enabled, the output will be identical for both files, and will be determined by which file gets cached first.
 [2009-02-16 15:00 UTC] shire@php.net
This is known/expected behavior, as PHP handles these values at parse time rather than run-time, which means APC is caching the results of the first parse.  This is why you get the same (cached) behavior on multiple requests.  Unfortunately this isn't something we can currently easily fix, our best bet is probably to figure out ways to make users more aware of when this is occurring.
 [2009-03-01 14:30 UTC] gizmo at aoaforums dot com
After some research, it appears eAccelerator can be configured to store the file based on an MD5 hash of the file path rather than the inode.  This seems to solve the problem rather elegantly.  Perhaps something similar could be done for APC?
 [2009-03-02 04:34 UTC] gopalv82 at yahoo dot com
We do that too - just set apc.stat=0; and it'll never touch the disk & will use the path as a key.

But on-disk changes while running an app will not be reflected in the cache, because the nostat mode was written to increase performance rather than fix this problem.
 [2009-03-02 14:39 UTC] shire@php.net
Perhaps we could offer a mixed mode of these two options (full path stat), however this would mean adding yet another mode to the confusion and we'd need to allow the old way for those wanting this functionality.  

It would be nice to consolidate these different modes but I'm not seeing an easy way to do that and make everyone happy.

The other option of course is to rewrite on the fly these opcodes, but I don't think that's reasonable.

(marking this as a feature request, maybe there's something clever we can come up with?)
 [2010-04-20 12:26 UTC] mail at tiago-neves dot com
Are there any developments on this request?
 [2016-08-31 15:12 UTC] cmb@php.net
-Status: Open +Status: Wont fix -Assigned To: +Assigned To: cmb
 [2016-08-31 15:12 UTC] cmb@php.net
According to <https://bugs.php.net/69618>, APC support has been
discontinued in favor of OPcache, APCu, the session upload
progress API and WinCache. Therefore this issue won't get fixed.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 21 14:01:32 2024 UTC