ZF-11921: Race condition in plugin loader include file cache
Description
There seems to be a race condition in Zend_Loader_PluginLoader. The symptoms are there is a missing '<?php' in the include file. I have analysed the code a bit and the following looks like a plausible explanation:
The code that appends the files to include file cache is not atomic and in some cases this can cause <?php to be omitted from the include file.
I think roughly the following happens:
a) Process 1 enters the routing, checks that file does not exist and adds '<php' to the string b) Process 1 starts file_put_contents c) At the same time process 2 enters the routine, checks that file does not exist and gets the file contents
If the C happens before file has been written the end results could end up being corrupted. This can be fixed by adding RW locking into the routine.
protected static function _appendIncFile($incFile)
{
if (!file_exists(self::$_includeFileCache)) {
$file = '<?php';
} else {
$file = file_get_contents(self::$_includeFileCache);
}
if (!strstr($file, $incFile)) {
$file .= "\ninclude_once '$incFile';";
file_put_contents(self::$_includeFileCache, $file);
}
}
Comments
Posted by Yosh de Vos (yosh) on 2012-08-23T10:37:43.000+0000
I have the same problem. All worked fine in our development environment, but as soon as I deployed it to production the contents of plugin loader cache file is returned to the webbrowser because of the missing <?php tag.
Multiple requests try to generate the file at the same time causing problems. Locking the file should solve this problem.
Posted by Lauri Elevant (clon) on 2012-11-21T00:46:58.000+0000
This bug seems to occur a few times a year, especially after new deployments. It is rather annoying as the site stays down until you delete the corrupted file.
We seem to have fixed the race condition with a simple locking mechanism - see the code below. Anyone with the paperwork done can perhaps commit this.