I can't find what can cause the following line in my PHP script:

        if ($this->_flock = @fopen($name, "a+b")) {

executed in a member function of a class like:

class IniFile {
    var $_name, $_data, $_f, $_flock;
    function IniFile($file, $lockmode = LOCK_EX) {
        $this->_name = $file;
        $this->load($lockmode);
    }
    function clear() {
        $this->_data = array();
    }
    function load($lockmode = LOCK_EX) {
        $this->clear();
        clearstatcache();
        $name = $this->_name . '.tmp';
        if ($this->_flock = @fopen($name, "a+b")) {
        //...
        }
        //...
     }
     //...
}

to sometimes create a file named "a+b" at unpredictable times. This occurs
under stress conditions with my current installation of PHP 4.3.1 (powered
by Zend Optimizer with Zend Engine v1.3.0) running in safe mode.
The files are stored in a NFS volume, but the folder into which it is
created is used by a single NFS-client host, and locking is provided by a
external network service...

I tried with single quotes instead of double quotes for the 'a+b' parameter
(because of the difference of semantics for variable substitutions), or
tried with 'a+' and it does not change anything.

I suspect this is a bug in the memory management of PHP 4 (running in
FastCGI mode on Linux), and it could be used by a the garbage collector
which mixes some string pointers used in parameters of class member function
calls (here it would incorrectly swap the String values of the two arguments
of non-class functions fopen() invoked from a member class).

I even tried to use (for stress tests) a static constant filename instead of
the $name local variable. Initially I did not use $name, but directly the
expression:
     $this->_name . '.tmp'
which was also failing, but much more often.

The problem is that I detected this bug which is also a severe security
issue as it has also affected randomly various places where instance methods
are used with multiple string arguments, which are clearly swapped
randomly...

To make sure it was effectively the case, I ran a script that performs such
fopen() calls with intermediate string expressions in a tight loop, and this
occured about every 20,000 to 30,000 loops on average...
Then I performed a similar script that was computing string concatenation
with member variables, with constant results, to send it to a local network
service where I could monitor the difference of results, and I found that
string parameters were swapped too, at random times, probably by the garbage
collector. This bug affects only PHP running as a FastCGI daemon, bit not
the standalone CGI version.

Reply via email to