Package home | Report new bug | New search | Development Roadmap Status: Open | Feedback | All | Closed Since Version 1.8.3

Bug #18192 Improper file opening in _write method
Submitted: 2011-01-13 17:16 UTC
From: roborg Assigned: tacker
Status: Suspended Package: Cache_Lite (version 1.7.8)
PHP Version: Irrelevant OS: All
Roadmaps: (Not assigned)    
Subscription  


 [2011-01-13 17:16 UTC] roborg (Gregory Pinnington)
Description: ------------ The cache file to write to is opened with mode "wb" before it is locked, so a read can occur between the file being opened (and truncated) and locked. Running two copies of the test script simultaneously will show this behaviour. Suggested fix is to change line 766 onwards from: $fp = @fopen($this->_file, "wb"); if ($fp) { if ($this->_fileLocking) @flock($fp, LOCK_EX); to $fp = @fopen($this->_file, "cb"); if ($fp) { if ($this->_fileLocking) @flock($fp, LOCK_EX); ftruncate($fp, 0); Test script: --------------- <?php require_once 'Cache/Lite.php'; $c = new Cache_Lite(array('cacheDir' => '.')); $str = 'test'; for ($i = 0; $i < 10000; $i++) { if (!$c->save('test', $str)) die('Error saving'); if ($c->get('test') != $str) die('Wrong data'); } Expected result: ---------------- No output Actual result: -------------- die() is called

Comments

 [2011-01-13 17:25 UTC] roborg (Gregory Pinnington)
 [2011-01-14 16:50 UTC] tacker (Markus Tacker)
-Status: Open +Status: Verified -PHP Version: 5.2.8 +PHP Version: Irrelevant -Assigned To: +Assigned To: tacker
 [2011-02-07 16:52 UTC] tacker (Markus Tacker)
-Status: Verified +Status: Feedback
Gregory, I cannot reproduce the bug via the console. I've added this script: http://svn.php.net/viewvc/pear/packages/Cache_Lite/trunk/tests/pearbug18192.php?revision=308092&view=markup Executing it via: php pearbug18192-sub.php & php pearbug18192-sub.php & php pearbug18192-sub.php & php pearbug18192-sub.php & php pearbug18192-sub.php & php pearbug18192-sub.php & php pearbug18192-sub.php & php pearbug18192-sub.php & php pearbug18192-sub.php & php pearbug18192-sub.php & php pearbug18192-sub.php & php pearbug18192-sub.php & php pearbug18192-sub.php & php pearbug18192-sub.php does not yield a single error.
 [2011-02-24 15:07 UTC] roborg (Gregory Pinnington)
That's odd - I just ran your script on my server and was flooded with "Error saving" and "Wrong data". I ran your script & command line on Red Hat Enterprise Linux Server release 5.5 (Tikanga) with PHP 5.3.3 but I verified it using Apache and PHP 5.3.5 on Windows XP as well. Both machines are multi-processor.
 [2011-02-26 19:23 UTC] tacker (Markus Tacker)
-Status: Feedback +Status: Verified
Ok, I can vereify this also on an archlinux machine with PHP 5.3.5 and suhosin
 [2011-02-26 19:59 UTC] tacker (Markus Tacker)
-Status: Verified +Status: Suspended
Your changes will not fix the "problem". The internals of Cache_Lite do not have a global cache locking. Instead during a write, the cache file is locked, data is written, file is unlocked and then the written data is verified with a second lock. In between cache writes can happen from other processes. See _writeAndControl() for references. So what you are really seeing are results of locking not beeing thoroughly executed. A real fix would a far more complete rewrite of the locking mechanism.