From:             
Operating system: GNU/Linux
PHP version:      5.4Git-2012-05-18 (Git)
Package:          XML Writer
Bug Type:         Bug
Bug description:Exploitable memory leak in the XML Writer module

Description:
------------

Short story : 
- - - - - - -

Calling xmlwriter_open_uri(x) in a PHP script leaks memory when x =
"file:///" 
or x = "file://localhost/". This is due to the fact that a xmlURI object
isn't 
freed in the _xmlwriter_get_valid_file_path() function from 
'ext/xmlwriter/php_xmlwriter.c'. In a web server setup with mod_php, the
leaked 
memory isn't released until the web server is restarted. This bug seems to
be 
present in all recent versions of PHP (5.3 and 5.4 branches): I have been
able 
to reproduce it on several versions of PHP 5.3 under GNU/Linux and Mac OS
X, and 
I provide a patch for the 5.4Git-2012-05-18 version.

More details :
- - - - - - - 

There seems to be a memory leak in the xmlwriter_open_uri() function when
it is 
called with the "file:///" parameter. This bug is triggered in the internal

_xmlwriter_get_valid_file_path() function from
'ext/xmlwriter/php_xmlwriter.c', 
at line 618 in PHP 5.3.13 (or line 616 in PHP 5.4.3): 

            if (source[sizeof("file:///") - 1] == '\0') { 
                return NULL;
            }

This "return NULL;" statement exits the function without freeing the 'uri'

variable that has been allocated with xmlCreateURI(). The following line
should 
be added before "return NULL": 

                xmlFreeURI(uri);

The same problem can be found a few lines later, when testing whether the 
'source' string is equal to "file://localhost/". Consequently, calling 
xmlwriter_open_uri() with the "file://localhost/" parameter also triggers
the 
bug.

In a web server setup with mod_php, since xmlCreateURI() allocates
persistent 
memory, the leaked memory won't be released until the web server is
restarted. 
On my machine, with Ubuntu 11.10, PHP-5.3.13 (Apache 2 with mod_php) and
libxml 
2.7.8, after calling xmlwriter_open_uri("file:///") a million times in a
PHP 
script, one of the background apache2 processes eats up ~156.3MB of memory

(VmRSS). If this function is called 10 million times instead, the
background 
apache2 process eats up ~1.53GB of memory: each call to 
xmlwriter_open_uri("file:///") seems to leak around 160 bytes. Calling the

function 30 million times is sufficient to completely overwhelm my machine
(with 
4GB of physical RAM).

This bug seems easily exploitable by a malicious user who plans to saturate
the 
memory of a server on which he has the ability to execute PHP scripts.
Indeed, a 
simple loop calling xmlwriter_open_uri("file:///") repeatedly would use up
all 
memory very quickly: looping until the default 30 second PHP timeout
results in 
an apache2 process that consumes 508.4MB on my hardware, and the script can
be 
called many times, concurrently or not. Moreover, if a PHP script uses a
HTML 
form variable as the argument to xmlwriter_open_uri(), a hacker could set
this 
variable to "file:///" (or "file://localhost/") and call the script
repeatedly 
to use up all memory.

I have been able to activate this bug on Mac OS X Lion (10.7, PHP 5.3.6),
with 
similar results.

The patch submitted here fixes this issue for the latest Git version (5.4 
branch).

Test script:
---------------
<?php

    // After running this script on PHP-5.3.13 (GNU/Linux) with libxml
2.7.8, 
    // an apache2 process using ~156.3MB of memory runs in the background
until
    // Apache is restarted. With 1,000,000,000 iterations, this process
uses
    // 1.53GB of memory. Each iteration seems to leak around 160 bytes.

    for ($i = 0; $i < 1000000; $i++)
    {
        xmlwriter_open_uri("file:///");
        // Or: xmlwriter_open_uri("file://localhost/");
    }

?>

Expected result:
----------------
After the script is executed, the memory used by apache2 processes
shouldn't 
increase.

Actual result:
--------------
After the script is executed, an apache2 process that uses around ~160MB of

memory runs in the background. Executing the script several times keeps
eating up 
more memory.

-- 
Edit bug report at https://bugs.php.net/bug.php?id=62064&edit=1
-- 
Try a snapshot (PHP 5.4):            
https://bugs.php.net/fix.php?id=62064&r=trysnapshot54
Try a snapshot (PHP 5.3):            
https://bugs.php.net/fix.php?id=62064&r=trysnapshot53
Try a snapshot (trunk):              
https://bugs.php.net/fix.php?id=62064&r=trysnapshottrunk
Fixed in SVN:                        
https://bugs.php.net/fix.php?id=62064&r=fixed
Fixed in SVN and need be documented: 
https://bugs.php.net/fix.php?id=62064&r=needdocs
Fixed in release:                    
https://bugs.php.net/fix.php?id=62064&r=alreadyfixed
Need backtrace:                      
https://bugs.php.net/fix.php?id=62064&r=needtrace
Need Reproduce Script:               
https://bugs.php.net/fix.php?id=62064&r=needscript
Try newer version:                   
https://bugs.php.net/fix.php?id=62064&r=oldversion
Not developer issue:                 
https://bugs.php.net/fix.php?id=62064&r=support
Expected behavior:                   
https://bugs.php.net/fix.php?id=62064&r=notwrong
Not enough info:                     
https://bugs.php.net/fix.php?id=62064&r=notenoughinfo
Submitted twice:                     
https://bugs.php.net/fix.php?id=62064&r=submittedtwice
register_globals:                    
https://bugs.php.net/fix.php?id=62064&r=globals
PHP 4 support discontinued:          
https://bugs.php.net/fix.php?id=62064&r=php4
Daylight Savings:                    https://bugs.php.net/fix.php?id=62064&r=dst
IIS Stability:                       
https://bugs.php.net/fix.php?id=62064&r=isapi
Install GNU Sed:                     
https://bugs.php.net/fix.php?id=62064&r=gnused
Floating point limitations:          
https://bugs.php.net/fix.php?id=62064&r=float
No Zend Extensions:                  
https://bugs.php.net/fix.php?id=62064&r=nozend
MySQL Configuration Error:           
https://bugs.php.net/fix.php?id=62064&r=mysqlcfg

Reply via email to