php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #56577 uses cached code for other files with identical filename
Submitted: 2005-10-04 07:42 UTC Modified: 2006-02-24 00:15 UTC
From: joris at phasetwo dot be Assigned:
Status: Not a bug Package: APC (PECL)
PHP Version: 4.3.10 OS: Debian GNU/Linux stable
Private report: No CVE-ID: None
 [2005-10-04 07:42 UTC] joris at phasetwo dot be
Description:
------------
On a hosting environement with multiple virtual hosts, we noticed that APC 'sometimes' uses the cache for a different file with the same basename.

Eg, /host1/index.php is cached, and that cache is used for /host2/index.php. This naturally causes some highly undesireable effects.

When this happens, it is repeatable for the same file over and over again (eg, hitting refresh still shows the cache for the wrong file being run).

Clearing the cache by restarting the webserver (apache 1.3) solves the situation.


As far as I know, there is no reliable way to reproduce this bug, apart from brute tryout.


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2005-10-17 07:01 UTC] stefan1281 at gmx dot de
The same happens on our Servers,
we noticed that APC cached the index.php for not logged in Users on a portal after ther login the users are redirected to the same index.php with some new parameters and the APC allways sends back the "index.php" the user has seen as he wasnt logged in! 

After deactivateing the APC this problem was solved - so cant only be the APC!
 [2005-10-17 07:01 UTC] stefan1281 at gmx dot de
Is there a workaround for that problem?
 [2005-10-17 10:46 UTC] rasmus@php.net
Joris, APC doesn't actually care about filenames at all.  It uses the file's device+inode as the hash key.  You can rename a file all you want and if you look at the status page you will see the original filename listed and no new entries for the renamed version assuming you didn't change the file's modification time.  So, the issue must be something else.  Which filesystem do these files live on?  Is it some sort of network filesystem where a stat might fail, or the stat could come back with the wrong data?
 [2005-10-17 10:58 UTC] rasmus@php.net
Hrm..  Another thought on this one.  One of the things I do is that I grab the stat struct for the primary file requested from Apache in order to save a stat call.  I don't quite see how, but if there is some way that Apache is returning the wrong stat struct I can see this happening.  If you know your way around a C compiler, go into apc_cache.c and find the call to sapi_get_stat() and get rid of it.  The logic there is pretty simple, just force it to always do a full apc_stat() call instead.  If that fixes it, we need to figure out why in the world sapi_get_stat() is returning the wrong thing.
 [2006-02-24 00:15 UTC] rasmus@php.net
I still don't see how this could be happening the way it is described.  Try current CVS and digging a bit deeper and reopen this if you get anywhere.  With the current info in this report I don't have anywhere near enough to go on.
 [2008-06-02 18:36 UTC] rpeters at icomproductions dot ca
I too am experiencing this same issue.
Our setup is as follows:
/var/www/vhosts/site1/httpdocs/common.php
/var/www/vhosts/site1/httpdocs/index.php
/var/www/vhosts/site1/httpdocs/includes/prepend.inc.php
/var/www/vhosts/site1/httpdocs/includes/configuration.inc.php
/var/www/vhosts/site2/httpdocs/common.php
/var/www/vhosts/site2/httpdocs/index.php
/var/www/vhosts/site2/httpdocs/includes/prepend.inc.php
/var/www/vhosts/site2/httpdocs/includes/configuration.inc.php

The two common.php files are hard-linked to each other (same inode).
The two index.php files are hard-linked to each other (same inode).
The two prepend.inc.php files are hard-linked to each other (same inode).
The two configuration.inc.php files are unique (different inodes).

index.php contains: require('common.php');
common.php contains: require('includes/prepend.inc.php');
prepend.inc.php contains: require(dirname(__FILE__) . '/configuration.inc.php');

configuration.inc.php defines some constants, such as:
define ('__DOCROOT__', '/var/www/vhosts/site1/httpdocs');

Our issue is that after restarting Apache with APC active, and we hit site1, everything works, but then, hitting site2, we find that __DOCROOT__ is defined as /var/www/vhosts/site1/httpdocs rather than /var/www/vhosts/site2/httpdocs, which it would be if APC were not active.

This makes me believe that APC has issues with some combination of:
1) Hard-linked files including non-linked files
2) Virtual hosts with similar filenames
3) Constants defined during seperate page hits

Unfortunately, this is a production server, and we can not afford the down-time to debug this issue further.
 [2008-06-02 18:38 UTC] rpeters at icomproductions dot ca
I should note that our issues were experienced with v3.0.18 and PHP Version 5.2.2 on Apache 2.0.52.
 [2008-06-02 18:40 UTC] rpeters at icomproductions dot ca
dirname(__FILE__) also seems like a prime candidate for issues, since the results of this would differ on the different hosts, even though __FILE__ refers to the same inode each time.
 [2008-06-02 19:03 UTC] rpeters at icomproductions dot ca
Confirmed in v3.0.19.
The following code behaves differently with APC installed.

1\test.php
1\testDest.php
2\test.php
2\testDest.php

1\test.php:
<?php
require(dirname(__FILE__) . '/testDest.php');
?>

2\test.php created by "cp -l ../1/test.php"

1\testDest.php:
<?php
echo 1;
?>

2\testDest.php:
<?php
echo 2;
?>

Without APC, 1/test.php displays "1", and 2/test.php displays "2". With it, both scripts will return the results of whichever one you hit first.
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Sun May 26 05:01:26 2019 UTC