Edit report at https://bugs.php.net/bug.php?id=64233&edit=1
ID: 64233
Comment by: andreas dot lindemann at de dot bp dot com
Reported by: andreas dot lindemann at de dot bp dot com
Summary: Soapserver::fault bus error on Solaris CLI/CGI/FPM
Status: Open
Type: Bug
Package: SOAP related
Operating System: Solaris 10
PHP Version: 5.4.11
Block user comment: N
Private report: N
New Comment:
Seem to have found the main issue.
"new_len" is defined int in ext/soap/soap.c in function serialize_response_call:
int new_len;
xmlNodePtr node = xmlNewNode(NULL, BAD_CAST("faultcode"));
char *str = php_escape_html_entities((unsigned char*)Z_STRVAL_PP(tmp),
Z_STRLEN_PP(tmp), &new_len, 0, 0, NULL TSRMLS_CC);
However, php_escape_html_entities() handles new_len as size_t.
PHPAPI char *php_escape_html_entities(unsigned char *old, size_t oldlen, size_t
*newlen, int all, int flags, char *hint_charset TSRMLS_DC)
php_escape_html_entities_ex() tracks the string length in a
size_t len
When assigning the size_t value to the int pointer, PHP crashes.
This can be reproduced by a very simple C program on Solaris 64 bit which just
replicates this process:
----------------------
#include <stdio.h>
int testfunc(size_t *dummy)
{
size_t len;
len = 5;
*dummy = len;
}
int main()
{
int test;
testfunc(&test);
return 0;
}
----------------------
$ gcc -m64 test.c
test.c: In function 'main':
test.c:15:3: warning: passing argument 1 of 'testfunc' from incompatible
pointer type [enabled by default]
test.c:3:5: note: expected 'size_t *' but argument is of type 'int *'
$ ./a.out
Bus Error (core dumped)
Note: On 64-bit Linux, this program runs without errors! So you cannot
reproduce this issue on Linux!
There seem to be 2 ways to fix this:
1) Change new_len declaration to size_t in ext/soap/soap.c -> works fine, BUT
new_len is also passed to xmlNodeSetContentLen, which expects this parameter to
be int. Can use a cast to convert the size_t to int though, shouldn't matter
unless your string exceeds MAX_INT?
2) Change php_escape_html_entities and php_escape_html_entities_ex in
ext/standard/html.c to expect newlen as int and declare "len" as int as well.
To me, 1) sounds to be the easier solution which only impacts soap.c really,
leaving other places where php_escape_html_entities is used untouched.
Sounds reasonable?
Previous Comments:
------------------------------------------------------------------------
[2013-05-27 06:49:23] andreas dot lindemann at de dot bp dot com
Now with php 5.4.14 and still trying to narrow this down.
So far, I've narrowed it down to a single line of code.
The issue seems to be caused in ext/standard/html.c at the very end of
php_escape_html_entities_ex():
replaced[len] = '\0'; // This seems to be fine
*newlen = len; // <-- This line crashes PHP
return replaced;
}
It seems the issue occurs when accessing the "len" variable. If I add another
line just before the *newlen = len; line, i.e. for getting the value of "len"
out to the php logfile, PHP crashes on that new line as well:
Example (not a nice one):
php_error_docref0(NULL TSRMLS_CC, E_STRICT, "debug 1");
replaced[len] = '\0';
// Next line still goes to the log
php_error_docref0(NULL TSRMLS_CC, E_STRICT, "debug 2");
// Next line crashes PHP
php_error_docref0(NULL TSRMLS_CC, E_STRICT, (char*)len);
// This won't be executed:
*newlen = len;
// And we'll never see this:
php_error_docref0(NULL TSRMLS_CC, E_STRICT, "debug 3");
return replaced;
}
Any ideas?
------------------------------------------------------------------------
[2013-03-19 09:29:57] andreas dot lindemann at de dot bp dot com
Any chance of fixing or reproducing this?
If I can be of assistance, i.e. running some debug build to give more insight
into the issue or so, please let me know.
For now I've made a change to the soap extension to not run through the
php_escape_html_entities_ex function. This is probably neither a good idea nor
anywhere near a proper fix, considering that I've only got a very basic idea of
C, but at least it throws the SoapFaults correctly to the client and doesn't
crash the PHP process.
--- ext/soap/soap.c.orig 2013-01-16 08:10:30.000000000 +0100
+++ ext/soap/soap.c 2013-03-11 12:30:34.497971000 +0100
@@ -3881,7 +3881,8 @@
if (zend_hash_find(prop, "faultcode",
sizeof("faultcode"), (void**)&tmp) == SUCCESS) {
int new_len;
xmlNodePtr node = xmlNewNode(NULL,
BAD_CAST("faultcode"));
- char *str = php_escape_html_entities((unsigned
char*)Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), &new_len, 0, 0, NULL TSRMLS_CC);
+ char *str = (unsigned char*)Z_STRVAL_PP(tmp);
xmlAddChild(param, node);
if (fault_ns) {
xmlNsPtr nsptr = encode_add_ns(node,
fault_ns);
@@ -3906,7 +3907,8 @@
if (zend_hash_find(prop, "faultcode",
sizeof("faultcode"), (void**)&tmp) == SUCCESS) {
int new_len;
xmlNodePtr node = xmlNewChild(param, ns,
BAD_CAST("Code"), NULL);
- char *str = php_escape_html_entities((unsigned
char*)Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), &new_len, 0, 0, NULL TSRMLS_CC);
+ char *str = (unsigned char*)Z_STRVAL_PP(tmp);
node = xmlNewChild(node, ns, BAD_CAST("Value"),
NULL);
if (fault_ns) {
xmlNsPtr nsptr = encode_add_ns(node,
fault_ns);
------------------------------------------------------------------------
[2013-02-21 06:09:23] andreas dot lindemann at de dot bp dot com
This may be specific to Solaris 64bit.
I tried to reproduce on Linux 64bit (SuSE Linux Enterprise), but no issue there
as well.
However no problem to reproduce this on 5 of our Solaris Sparc servers, all are
showing the same bus error and backtrace.
------------------------------------------------------------------------
[2013-02-21 05:34:56] [email protected]
no luck to reproduce this on centOS.
------------------------------------------------------------------------
[2013-02-18 12:47:42] andreas dot lindemann at de dot bp dot com
Tried to reproduce on older versions: 5.4.6 fails with same error.
PHP 5.3.21 however works correctly:
$ ./php -v
PHP 5.3.21 (cli) (built: Feb 18 2013 13:16:03)
Copyright (c) 1997-2013 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2013 Zend Technologies
$ ./php -f test_script.php
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body><SOAP-ENV:Fault><faultcode>SOAP-ENV:Server</faultcode>
<faultstring>SoapServer::SoapServer(): Invalid parameters</faultstring></SOAP-
ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>
Something must have been broken between 5.3.21 and 5.4.6+, maybe this helps
with
the investigation.
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
https://bugs.php.net/bug.php?id=64233
--
Edit this bug report at https://bugs.php.net/bug.php?id=64233&edit=1