Pluf_Cache_File contains a race condition in its get() method when
two parallel requests want to read a specific cache file whose
timeout has been reached (this pops up every couple of hours on our
setup).
The problematic code is this:
if (!file_exists($fname)) return $default;
list($timeout, $content) =
explode("\n", file_get_contents($fname), 2);
if ($timeout < time()) {
@unlink($fname);
...
}
file_get_contents() will fail if the file has been deleted just
after file_exists() returned true. One could now start build some
complex struct involving PHP's flock function, but I think it might
already be enough to rewrite it like this:
$data = @file_get_contents($fname);
if ($data === false) return $default;
list($timeout, $content) = explode("\n", $data, 2);
if ($timeout < time()) {
@unlink($fname);
...
}
Opinions?
Reported by Thomas Keller, Oct 14, 2010
Pluf_Cache_File contains a race condition in its get() method when two parallel requests want to read a specific cache file whose timeout has been reached (this pops up every couple of hours on our setup). The problematic code is this: if (!file_exists($fname)) return $default; list($timeout, $content) = explode("\n", file_get_contents($fname), 2); if ($timeout < time()) { @unlink($fname); ... } file_get_contents() will fail if the file has been deleted just after file_exists() returned true. One could now start build some complex struct involving PHP's flock function, but I think it might already be enough to rewrite it like this: $data = @file_get_contents($fname); if ($data === false) return $default; list($timeout, $content) = explode("\n", $data, 2); if ($timeout < time()) { @unlink($fname); ... } Opinions?