php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #66150 SOAP WSDL cache race condition causes Segmentation Fault
Submitted: 2013-11-22 17:12 UTC Modified: -
Votes:2
Avg. Score:4.5 ± 0.5
Reproduced:1 of 1 (100.0%)
Same Version:0 (0.0%)
Same OS:1 (100.0%)
From: askalski at gmail dot com Assigned:
Status: Open Package: SOAP related
PHP Version: master-Git-2013-11-22 (Git) OS: Linux
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: askalski at gmail dot com
New email:
PHP Version: OS:

 

 [2013-11-22 17:12 UTC] askalski at gmail dot com
Description:
------------
The SOAP module does not write out the WSDL cache files atomically (temp file + rename.)  Thus a race condition exists where if another process attempts to read the partially written cache file, a Segmentation Fault occurs in get_sdl_from_cache.


Test script:
---------------
The issue is easiest to reproduce with a large WSDL file, on a multi-core machine with relatively slow disks.  (Don't point your WSDL cache directory at a tmpfs or SSD filesystem.)

Download the following files into the script directory before testing:

http://www.paypalobjects.com/wsdl/PayPalSvc.wsdl
http://www.paypalobjects.com/wsdl/CoreComponentTypes.xsd
http://www.paypalobjects.com/wsdl/eBLBaseComponents.xsd
http://www.paypalobjects.com/wsdl/EnhancedDataTypes.xsd

<?php
ini_set("soap.wsdl_cache_ttl", "1");
$s = new soapclient("PayPalSvc.wsdl");
?>

Use Apache Bench or other stress testing tool to hit the test script with concurrency.  Watch the error logs for the segmentation faults:
$ ab -k -n20000 -c20 http://localhost/path/to/soap-test-script.php


Expected result:
----------------
No segmentation fault.  PHP should write to a temporary file, and use rename() to replace the cache file when finished.  There should be some protection against stampedes -- other concurrent processes should be able to use the old cache file (if it exists) while it is being rebuilt.


Actual result:
--------------
Two example gdb backtraces follow (line numbers refer to php-src git commit id 7f0d637de4b0fe169dcae4437a86077ece3e3acd):

(gdb) bt 5
#0  memcpy () at ../sysdeps/x86_64/memcpy.S:399
#1  0x00007f66fe9c07af in sdl_deserialize_string (in=0x7fff9a94d650) at /home/askalski/php-src/ext/soap/php_sdl.c:1208
#2  0x00007f66fe9c5470 in sdl_deserialize_type (type=0x7f671082dac8, types=0x7f67094994b0, encoders=0x7f67107c4be0, 
    in=0x7fff9a94d650) at /home/askalski/php-src/ext/soap/php_sdl.c:1326
#3  0x00007f66fe9c55cc in sdl_deserialize_type (type=0x7f67107c0ab8, types=0x7f67094994b0, encoders=0x7f67107c4be0, 
    in=0x7fff9a94d650) at /home/askalski/php-src/ext/soap/php_sdl.c:1378
#4  0x00007f66fe9cbeef in get_sdl_from_cache (this_ptr=<value optimized out>, 
    uri=0x7f670937d240 "http://127.0.10.1/~askalski/soap/PayPalSvc.wsdl", cache_wsdl=<value optimized out>)
    at /home/askalski/php-src/ext/soap/php_sdl.c:1642
(More stack frames follow...)

(gdb) bt 5
#0  0x00007f66fe9c54ec in sdl_deserialize_type (type=0x7f671090a8c0, types=0x7f67107e2ad0, encoders=0x7f67107efc78, 
    in=0x7fff9a94d650) at /home/askalski/php-src/ext/soap/php_sdl.c:1335
#1  0x00007f66fe9c55cc in sdl_deserialize_type (type=0x7f67094a32a8, types=0x7f67107e2ad0, encoders=0x7f67107efc78, 
    in=0x7fff9a94d650) at /home/askalski/php-src/ext/soap/php_sdl.c:1378
#2  0x00007f66fe9cbeef in get_sdl_from_cache (this_ptr=<value optimized out>, 
    uri=0x7f670937d240 "http://127.0.10.1/~askalski/soap/PayPalSvc.wsdl", cache_wsdl=<value optimized out>)
    at /home/askalski/php-src/ext/soap/php_sdl.c:1642
#3  get_sdl (this_ptr=<value optimized out>, uri=0x7f670937d240 "http://127.0.10.1/~askalski/soap/PayPalSvc.wsdl", 
    cache_wsdl=<value optimized out>) at /home/askalski/php-src/ext/soap/php_sdl.c:3251
#4  0x00007f66fe99bcdd in zim_SoapClient_SoapClient (ht=1, return_value=<value optimized out>, 
    return_value_ptr=<value optimized out>, this_ptr=0x7f67094993e0, return_value_used=<value optimized out>)
    at /home/askalski/php-src/ext/soap/soap.c:2520
(More stack frames follow...)


Patches

Add a Patch

Pull Requests

Add a Pull Request

 
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Tue Feb 25 20:01:29 2020 UTC