From:             hiroaki dot kawai at gmail dot com
Operating system: 
PHP version:      5.3.1
PHP Bug Type:     XMLRPC-EPI related
Bug description:  system.multiCall cause Segmentation fault

Description:
------------
xmlrpc-epi supports system.multiCall(), which packs multiple xmlrpc 
method call transactions into one. Using this method in php extension 
cause php process crash.

The point was that we must let xmlrpc-epi to decode the multicall 
request. We must check the method name in the callback function.

This bug exists very long time. http://bugs.php.net/bug.php?id=27446

patch is available:
-------------------------
--- xmlrpc-epi-php.c.orig       2009-08-18 09:41:43.000000000 +0900
+++ xmlrpc-epi-php.c    2010-01-14 13:58:48.028867000 +0900
@@ -892,12 +892,23 @@
 static XMLRPC_VALUE php_xmlrpc_callback(XMLRPC_SERVER server, 
XMLRPC_REQUEST xRequest, void* data) /* {{{ */
 {
        xmlrpc_callback_data* pData = (xmlrpc_callback_data*)data;
+       zval** php_function;
        zval* xmlrpc_params;
        zval* callback_params[3];
        TSRMLS_FETCH();
 
        /* convert xmlrpc to native php types */
+       ZVAL_STRING(pData->xmlrpc_method, 
XMLRPC_RequestGetMethodName(xRequest), 1);
        xmlrpc_params = 
XMLRPC_to_PHP(XMLRPC_RequestGetData(xRequest));
+       
+       /* check if the called method has been previous registered */
+       if(zend_hash_find(Z_ARRVAL_P(pData->server->method_map),
+                      Z_STRVAL_P(pData->xmlrpc_method), 
+                      Z_STRLEN_P(pData->xmlrpc_method) + 1, 
+                      (void**)&php_function) == SUCCESS) {
+
+               pData->php_function = *php_function;
+       }
 
        /* setup data hoojum */
        callback_params[0] = pData->xmlrpc_method;
@@ -913,7 +924,7 @@
 
        zval_ptr_dtor(&xmlrpc_params);
 
-       return NULL;
+       return PHP_to_XMLRPC(pData->return_data TSRMLS_CC);
 }
 /* }}} */
 
@@ -1082,34 +1093,17 @@
 
                if (xRequest) {
                        const char* methodname = 
XMLRPC_RequestGetMethodName(xRequest);
-                       zval **php_function;
                        XMLRPC_VALUE xAnswer = NULL;
                        MAKE_STD_ZVAL(data.xmlrpc_method); /* init. 
very important.  spent a frustrating day finding this out. */
                        MAKE_STD_ZVAL(data.return_data);
                        Z_TYPE_P(data.return_data) = IS_NULL;  /* in 
case value is never init'd, we don't dtor to think it is a string or 
something */
                        Z_TYPE_P(data.xmlrpc_method) = IS_NULL;
 
-                       if (!methodname) {
-                               methodname = "";
-                       }
-            
                        /* setup some data to pass to the callback 
function */
-                       Z_STRVAL_P(data.xmlrpc_method) = 
estrdup(methodname);
-                       Z_STRLEN_P(data.xmlrpc_method) = 
strlen(methodname);
-                       Z_TYPE_P(data.xmlrpc_method) = IS_STRING;
                        data.caller_params = *caller_params;
                        data.php_executed = 0;
                        data.server = server;
 
-                       /* check if the called method has been 
previous registered */
-                       if (zend_hash_find(Z_ARRVAL_P(server-
>method_map),
-                                                               
Z_STRVAL_P(data.xmlrpc_method), 
-                                                               
Z_STRLEN_P(data.xmlrpc_method) + 1, 
-                                                               
(void**)&php_function) == SUCCESS) {
-
-                               data.php_function = *php_function;
-                       }
-
                        /* We could just call the php method directly 
ourselves at this point, but we do this 
                         * with a C callback in case the xmlrpc 
library ever implements some cool usage stats,
                         * or somesuch.
@@ -1119,7 +1113,7 @@
                                zval_dtor(data.return_data);
                                FREE_ZVAL(data.return_data);
                                data.return_data = 
XMLRPC_to_PHP(xAnswer);
-                       } else if (data.php_executed && 
!out.b_php_out) {
+                       } else if (data.php_executed && !out.b_php_out 
&& !xAnswer) {
                                xAnswer = 
PHP_to_XMLRPC(data.return_data TSRMLS_CC);
                        }
 



Reproduce code:
---------------
<?php
$req = '<?xml version="1.0"?>
<methodCall>
<methodName>system.multiCall</methodName>
<params><param><value><array><data>
<value><struct>
<member><name>methodName</name><value><string>testMethodA</string></value></member>
<member><name>params</name><value><array><data><value><string>A</string></value></data></array></value></member>
</struct></value>
<value><struct>
<member><name>methodName</name><value><string>testMethodB</string></value></member>
<member><name>params</name><value><array><data><value><string>B</string></value></data></array></value></member>
</struct></value>
</data></array></value></param></params>
</methodCall>';

function testA($methodName, $params, $var){ return "C"; }
function testB($methodName, $params, $var){ return "D"; }

$server = xmlrpc_server_create();
xmlrpc_server_register_method($server, 'testMethodA', 'testA');
xmlrpc_server_register_method($server, 'testMethodB', 'testB');
$res = xmlrpc_server_call_method($server, $req, null);
echo $res;


Expected result:
----------------
<?xml version="1.0" encoding="iso-8859-1"?>
<methodResponse>
<params>
 <param>
  <value>
   <array>
    <data>
     <value>
      <array>
       <data>
        <value>
         <string>C</string>
        </value>
       </data>
      </array>
     </value>
     <value>
      <array>
       <data>
        <value>
         <string>D</string>
        </value>
       </data>
      </array>
     </value>
    </data>
   </array>
  </value>
 </param>
</params>
</methodResponse>


Actual result:
--------------
Segmentation fault

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

Reply via email to