|  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #58377 wrong included file in mount-bind environment
Submitted: 2008-10-13 08:42 UTC Modified: 2008-10-30 08:21 UTC
From: starmen at email dot cz Assigned:
Status: Wont fix Package: APC (PECL)
PHP Version: 5.1.6 OS: Linux 2.6.9-67.0.4.EL RedHat
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2008-10-13 08:42 UTC] starmen at email dot cz

in our company we have one place for store all of our shared libs. Because we are using  open base dir in apache, we need to link this shared libs to all of our vhosts. We did it by "mount -o bind" command. Everything seems ok, but when we include any script from libs (which are mounted), than we all the time get version, which was cached in the first execute of the lib script and doesn't matter to the vhost. On the first look it's ok, content is same, but it's not correct. Difference is path. Look at reproduce code.

Reproduce code:
file .../1/tst.php

include_once '3/incl.php';

file .../2/tst.php

include_once '3/incl.php';
yes, same content as file .../1/tst.php

file .../3/incl.php

echo dirname(__FILE__);

now we mount-bind the .../3 directory to /1 and /2 directory

mkdir .../1/3
mkdir .../2/3
mount -o bind .../3 .../1/3
mount -o bind .../3 .../2/3

run .../1/tst.php
run .../2/tst.php (you must run this before cached version from first run is deleted from cache)

Expected result:

Actual result:


Add a Patch

Pull Requests

Add a Pull Request


AllCommentsChangesGit/SVN commitsRelated reports
 [2008-10-30 08:20 UTC] gopalv82 at yahoo dot com
Let me try to explain the real problem here. 

__FILE__ is a compile time constant. As far as APC is concerned, all it gets in the file stream is ".../1/3" as a pllain string.

in the scanner, here's how the replacement happens ...

	char *filename = zend_get_compiled_filename(TSRMLS_C);

	if (!filename) {
		filename = "";
	zendlval->value.str.len = strlen(filename);
	zendlval->value.str.val = estrndup(filename, zendlval->value.str.len);
	zendlval->type = IS_STRING;
	return T_FILE;

and the parser then passes it into the opcode stream as
a zval* string.

You could switch on apc.stat = 0 to use file paths as the keys instead of the inode+mtime, but then any file update will need a manual cache clear.

Then 1/3/inc1.php and 2/3/incl1.php end up as distinct cache entries, each compiled with their own constant strings. (or a realpath('.'), which is a kludgy slow way).
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Jul 25 16:01:28 2024 UTC