php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #68214 PHP5-FPM Segfault & Memory Corruption
Submitted: 2014-10-13 00:32 UTC Modified: 2015-02-11 11:26 UTC
Votes:5
Avg. Score:4.4 ± 0.8
Reproduced:5 of 5 (100.0%)
Same Version:1 (20.0%)
Same OS:3 (60.0%)
From: tomm at live dot co dot uk Assigned: ab (profile)
Status: Closed Package: Reproducible crash
PHP Version: 5.6.1 OS: Linux/Ubuntu 14.04 x64
Private report: No CVE-ID: None
 [2014-10-13 00:32 UTC] tomm at live dot co dot uk
Description:
------------
finfo_open causes segfault under php5-fpm and seems to corrupt memory.

I first noticed this on our production servers when we deployed PHP 5.6. A segfault occurs at finfo_open at:

https://github.com/zendframework/zf2/blob/master/library/Zend/Validator/File/MimeType.php#L205

A number of people using ZF2 report this problem:

https://github.com/zendframework/zf2/issues/6493

Note, if you restart php5-fpm it will take a couple of invocations of finfo_open before the segfault occurs. I've tried to pull a test script out but for some reason it does not segfault if you just invoke finfo_open in a simple file.

However, critically after the segfault occurs it appears there is some kind of memory corruption or similar.

After the segfault PHP5-FPM basically becomes unusable until it is restarted. This manifests itself in our application as PHP attempting to insert garbage data (as in random bytes) into the database for most of our queries.

We're using PHP as built here:
https://launchpad.net/~ondrej/+archive/ubuntu/php5-5.6
But also have the same issue building from source.

Backtrace:

(gdb) bt
#0  _zend_mm_free_int (heap=0x14492c0, p=0x7f8d13d6a058) at /home/ubuntu/php-src/Zend/zend_alloc.c:2104
#1  0x00000000006741ea in php_verror (docref=<optimized out>, params=params@entry=0xb4b34b "", type=type@entry=8, format=format@entry=0xa8ba9d "Warning: %s", args=args@entry=0x7ffffa05f988) at /home/ubuntu/php-src/main/main.c:944
#2  0x0000000000674640 in php_error_docref0 (docref=docref@entry=0x0, type=type@entry=8, format=format@entry=0xa8ba9d "Warning: %s") at /home/ubuntu/php-src/main/main.c:960
#3  0x00000000004df27b in file_magwarn (ms=ms@entry=0x1696e30, f=f@entry=0x7dcf81 "offset `%s' invalid") at /home/ubuntu/php-src/ext/fileinfo/libmagic/print.c:69
#4  0x00000000004d7793 in parse (action=<optimized out>, lineno=<optimized out>, line=<optimized out>, me=0x7ffffa05fbf0, ms=0x1696e30) at /home/ubuntu/php-src/ext/fileinfo/libmagic/apprentice.c:1595
#5  load_1 (ms=ms@entry=0x1696e30, action=action@entry=0, fn=fn@entry=0x166f6e0 "/usr/share/misc/magic.mgc", errs=errs@entry=0x7ffffa061c9c, mset=mset@entry=0x7ffffa061ca0)
    at /home/ubuntu/php-src/ext/fileinfo/libmagic/apprentice.c:1022
#6  0x00000000004d89b1 in apprentice_load (ms=ms@entry=0x1696e30, fn=fn@entry=0x166f6e0 "/usr/share/misc/magic.mgc", action=action@entry=0) at /home/ubuntu/php-src/ext/fileinfo/libmagic/apprentice.c:1216
#7  0x00000000004d9464 in apprentice_1 (ms=0x1696e30, fn=0x166f6e0 "/usr/share/misc/magic.mgc", action=0) at /home/ubuntu/php-src/ext/fileinfo/libmagic/apprentice.c:417
#8  0x00000000004d9c6a in file_apprentice (ms=0x1696e30, fn=0x166f6e0 "/usr/share/misc/magic.mgc", action=0) at /home/ubuntu/php-src/ext/fileinfo/libmagic/apprentice.c:603
#9  0x00000000004df04c in magic_load (ms=<optimized out>, magicfile=<optimized out>) at /home/ubuntu/php-src/ext/fileinfo/libmagic/magic.c:267
#10 0x00000000004d4dd8 in zif_finfo_open (ht=<optimized out>, return_value=0x168a540, return_value_ptr=<optimized out>, this_ptr=0x0, return_value_used=<optimized out>) at /home/ubuntu/php-src/ext/fileinfo/fileinfo.c:347
#11 0x00000000006c686b in dtrace_execute_internal (execute_data_ptr=<optimized out>, fci=<optimized out>, return_value_used=<optimized out>) at /home/ubuntu/php-src/Zend/zend_dtrace.c:97
#12 0x000000000077ad70 in zend_do_fcall_common_helper_SPEC (execute_data=<optimized out>) at /home/ubuntu/php-src/Zend/zend_vm_execute.h:560
#13 0x0000000000711c88 in execute_ex (execute_data=0x1620080) at /home/ubuntu/php-src/Zend/zend_vm_execute.h:363
#14 0x00000000006c6769 in dtrace_execute_ex (execute_data=<optimized out>) at /home/ubuntu/php-src/Zend/zend_dtrace.c:73
#15 0x000000000077b24a in zend_do_fcall_common_helper_SPEC (execute_data=<optimized out>) at /home/ubuntu/php-src/Zend/zend_vm_execute.h:592
#16 0x0000000000711c88 in execute_ex (execute_data=0x161f968) at /home/ubuntu/php-src/Zend/zend_vm_execute.h:363
#17 0x00000000006c6769 in dtrace_execute_ex (execute_data=<optimized out>) at /home/ubuntu/php-src/Zend/zend_dtrace.c:73
#18 0x000000000077b24a in zend_do_fcall_common_helper_SPEC (execute_data=<optimized out>) at /home/ubuntu/php-src/Zend/zend_vm_execute.h:592
#19 0x0000000000711c88 in execute_ex (execute_data=0x161f2d0) at /home/ubuntu/php-src/Zend/zend_vm_execute.h:363
#20 0x00000000006c6769 in dtrace_execute_ex (execute_data=<optimized out>) at /home/ubuntu/php-src/Zend/zend_dtrace.c:73
#21 0x00000000006d8e70 in zend_execute_scripts (type=type@entry=8, retval=retval@entry=0x0, file_count=file_count@entry=3) at /home/ubuntu/php-src/Zend/zend.c:1344
#22 0x00000000006767b5 in php_execute_script (primary_file=primary_file@entry=0x7ffffa067880) at /home/ubuntu/php-src/main/main.c:2586
#23 0x0000000000462a11 in main (argc=<optimized out>, argv=<optimized out>) at /home/ubuntu/php-src/sapi/fpm/fpm/fpm_main.c:1949

I've tried to debug the problem further, but I don't have enough C knowledge.

The error it's trying to handle is:

offset `\034\004\036\361' invalid

Which is present and fine in frame 3, file_magwarn. However, in frame 1 this error becomes corrupted:

buffer = 0x7f8d13d6a058 "H\240\326\023\215\177"
docref_buf = 0x1695d60 "0\\i\001"
target = <optimized out>
docref_target = <optimized out>
docref_root = <optimized out>
p = <optimized out>
buffer_len = 0
space = 0xb4b34b ""
class_name = <optimized out>
function = <optimized out>
origin_len = <optimized out>
origin = 0x16967e8 ""
message = 0x1695ca0 "finfo_open(): H\240\326\023\215\177"
is_function = <optimized out>

As you can see, the message has been replaced with some garbage from memory. I don't know how to work with the variadic arguments in frame 2 to see what is happening here.


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2014-12-23 03:07 UTC] turchanov at farpost dot com
This is a bug introduced by commit 03a37de9b3c4b9dc02aeeb5c5331ff89eac62515 (http://permalink.gmane.org/gmane.comp.php.cvs.general/64520) and occurs when PG(html_errors) is true and php_escape_html_entities was unable to convert a message (due to invalid utf8 sequence - that's another bug) and returns STR_EMPTY_ALLOC() interned string which certainly must not be efree-ed.

Patch is trivial. Give a feedback if it helps.

--- php-5.6.4/main/main.c.orig	2014-12-17 11:25:00.000000000 +1000
+++ php-5.6.4/main/main.c	2014-12-23 11:05:47.000000000 +1000
@@ -941,7 +941,7 @@ PHPAPI void php_verror(const char *docre
 			zend_hash_update(EG(active_symbol_table), "php_errormsg", sizeof("php_errormsg"), (void **) &tmp, sizeof(zval *), NULL);
 		}
 	}
-	efree(buffer);
+        str_efree(buffer);
 
 	php_error(type, "%s", message);
 	efree(message);
 [2015-02-02 14:44 UTC] nikic@php.net
Alternatively we might want to pass the ENT_HTML_SUBSTITUTE_ERRORS flag, so we still get an error, just with substitution characters.
 [2015-02-11 11:26 UTC] ab@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: ab
 [2015-02-11 11:26 UTC] ab@php.net
This was fixed with the PR from the bug #68996.

Thanks.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Mar 29 07:01:28 2024 UTC