Bug #52752 [Com]: Crash when lexing

From: Date: Wed, 21 Jun 2017 17:56:43 +0000
Subject: Bug #52752 [Com]: Crash when lexing
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-209622@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=52752&edit=1

 ID:                 52752
 Comment by:         zac at sprackett dot com
 Reported by:        paulgao at yeah dot net
 Summary:            Crash when lexing
 Status:             Verified
 Type:               Bug
 Package:            Scripting Engine problem
 Operating System:   Centos 5 32bit
 PHP Version:        5.3SVN-2010-08-31 (SVN)
 Block user comment: N
 Private report:     N

 New Comment:

This patch seems to help in my case.


diff -ruN php-5.6.30/Zend/zend_language_scanner.c php-5.6.30.patched/Zend/zend_language_scanner.c
--- php-5.6.30/Zend/zend_language_scanner.c	2017-01-18 19:17:47.000000000 -0500
+++ php-5.6.30.patched/Zend/zend_language_scanner.c	2017-06-21 13:18:53.000000000 -0400
@@ -125,6 +125,14 @@
 
 BEGIN_EXTERN_C()
 
+#ifndef _WIN32
+static sigjmp_buf sigbus_jmpbuf;
+static void sigbus_handler (int sig, siginfo_t *siginfo, void *ptr)
+{
+  siglongjmp(sigbus_jmpbuf, 1);
+}
+#endif
+
 static size_t encoding_filter_script_to_internal(unsigned char **to, size_t *to_length, const
unsigned char *from, size_t from_length TSRMLS_DC)
 {
 	const zend_encoding *internal_encoding = zend_multibyte_get_internal_encoding(TSRMLS_C);
@@ -580,6 +588,36 @@
 		}
 		compilation_successful=0;
 	} else {
+#ifndef _WIN32
+    struct sigaction sigbus_signal;
+    struct sigaction old_sigbus_signal;
+
+    memset(&sigbus_signal, 0, sizeof(sigbus_signal));
+    memset(&old_sigbus_signal, 0, sizeof(old_sigbus_signal));
+    sigbus_signal.sa_sigaction = sigbus_handler;
+    sigbus_signal.sa_flags = SA_SIGINFO;
+#endif
+
+#if defined(ZEND_SIGNALS) && !defined(_WIN32)
+    zend_try { zend_sigaction(SIGBUS, &sigbus_signal, &old_sigbus_signal TSRMLS_CC); }
zend_end_try();
+#elif !defined(_WIN32)
+    sigaction(SIGBUS, &sigbus_signal, &old_sigbus_signal);
+#endif
+
+#ifndef _WIN32
+    if (sigsetjmp(sigbus_jmpbuf, 1)) {
+			if (file_handle->type != ZEND_HANDLE_STREAM) {
+				file_handle->type = ZEND_HANDLE_STREAM;
+			}
+    }
+#endif
+
 		init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
 		CG(in_compilation) = 1;
 		CG(active_op_array) = op_array;
@@ -592,6 +630,13 @@
 			zend_bailout();
 		}
 		compilation_successful=1;
+
+#if defined(ZEND_SIGNALS) && !defined(_WIN32)
+  zend_try { zend_sigaction(SIGBUS, &old_sigbus_signal, 0 TSRMLS_CC); } zend_end_try();
+#elif !defined(_WIN32)
+  sigaction(SIGBUS, &old_sigbus_signal, 0);
+#endif
+
 	}
 
 	if (retval) {
diff -ruN php-5.6.30/Zend/zend_language_scanner.l php-5.6.30.patched/Zend/zend_language_scanner.l
--- php-5.6.30/Zend/zend_language_scanner.l	2017-01-18 19:17:47.000000000 -0500
+++ php-5.6.30.patched/Zend/zend_language_scanner.l	2017-06-21 13:18:38.000000000 -0400
@@ -123,6 +123,14 @@
 
 BEGIN_EXTERN_C()
 
+#ifndef _WIN32
+static sigjmp_buf sigbus_jmpbuf;
+static void sigbus_handler (int sig, siginfo_t *siginfo, void *ptr)
+{
+	siglongjmp(sigbus_jmpbuf, 1);
+}
+#endif
+ 
 static size_t encoding_filter_script_to_internal(unsigned char **to, size_t *to_length, const
unsigned char *from, size_t from_length TSRMLS_DC)
 {
 	const zend_encoding *internal_encoding = zend_multibyte_get_internal_encoding(TSRMLS_C);
@@ -578,6 +586,34 @@
 		}
 		compilation_successful=0;
 	} else {
+#ifndef _WIN32
+		struct sigaction sigbus_signal;
+		struct sigaction old_sigbus_signal;
+
+		memset(&sigbus_signal, 0, sizeof(sigbus_signal));
+		memset(&old_sigbus_signal, 0, sizeof(old_sigbus_signal));
+		sigbus_signal.sa_sigaction = sigbus_handler;
+		sigbus_signal.sa_flags = SA_SIGINFO;
+#endif
+
+#if defined(ZEND_SIGNALS) && !defined(_WIN32)
+		zend_try { zend_sigaction(SIGBUS, &sigbus_signal, &old_sigbus_signal TSRMLS_CC); }
zend_end_try();
+#elif !defined(_WIN32)
+		sigaction(SIGBUS, &sigbus_signal, &old_sigbus_signal);
+#endif
+
+#ifndef _WIN32
+		if (sigsetjmp(sigbus_jmpbuf, 1)) {
+			file_handle->type = ZEND_HANDLE_STREAM;
+		}
+#endif
+
 		init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
 		CG(in_compilation) = 1;
 		CG(active_op_array) = op_array;
@@ -590,6 +626,12 @@
 			zend_bailout();
 		}
 		compilation_successful=1;
+
+#if defined(ZEND_SIGNALS) && !defined(_WIN32)
+		zend_try { zend_sigaction(SIGBUS, &old_sigbus_signal, 0 TSRMLS_CC); } zend_end_try();
+#elif !defined(_WIN32)
+		sigaction(SIGBUS, &old_sigbus_signal, 0);
+#endif
 	}
 
 	if (retval) {


Previous Comments:
------------------------------------------------------------------------
[2017-06-14 15:59:13] zac at sprackett dot com

Anyone have any ideas?  this is a pretty long standing bug that is still evident in current PHP. 
We're getting hit by it pretty hard in production so I'm interested in any options
possible.  In the meantime, I've had to hack up PHP not to use mmap() for file io.

------------------------------------------------------------------------
[2017-06-10 00:25:24] zac at sprackett dot com

If I run two copies of the script below at once it happens pretty much instantly.  It's also
reproducible under php7.1.5:

<?php
while(true) {
    file_put_contents(__DIR__ . '/test.tpl', 'AAA<?php $string = "'.
str_repeat('A', mt_rand(1, 256 * 1024)) .'"; ?>BBB' . "\r\n");
    require __DIR__ . '/test.tpl';
}


* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=10,
address=0x102a79000)
  * frame #0: 0x000000010037243f php`lex_scan + 996
    frame #1: 0x0000000100388317 php`zendlex + 71
    frame #2: 0x000000010036d737 php`zendparse + 207
    frame #3: 0x0000000100371710 php`zend_compile + 103
    frame #4: 0x0000000100371656 php`compile_file + 55
    frame #5: 0x0000000100225d59 php`phar_compile_file + 267
    frame #6: 0x00000001012b16c3 xdebug.so`xdebug_compile_file + 12
    frame #7: 0x0000000100371899 php`compile_filename + 147
    frame #8: 0x00000001004342da php`zend_include_or_eval + 260
    frame #9: 0x00000001003fafe0 php`ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER + 40
    frame #10: 0x00000001003e2569 php`execute_ex + 56
    frame #11: 0x00000001012b1e7e xdebug.so`xdebug_execute_ex + 1927
    frame #12: 0x00000001003e27c7 php`zend_execute + 537
    frame #13: 0x00000001003a7415 php`zend_execute_scripts + 285
    frame #14: 0x000000010034fded php`php_execute_script + 611
    frame #15: 0x000000010043d3f1 php`do_cli + 3698
    frame #16: 0x000000010043c3f4 php`main + 1195
    frame #17: 0x00007fffbd01c515 libdyld.dylib`start + 1
    frame #18: 0x00007fffbd01c515 libdyld.dylib`start + 1

------------------------------------------------------------------------
[2017-06-09 19:28:14] pollita@php.net

It seems to be over-allocating on the stack.
Let's see if we can narrow the problem down to finding the file that's causing the
problem.

In gbd, jump to frame 5 and print file_handle as well as file_handle as well as
file_handle->filename and file_handle->opened_path

(gdb) f 5
(gdb) p file_handle
(gdb) p file_handle->filename
(gdb) p file_handle->opened_path

------------------------------------------------------------------------
[2017-06-09 19:17:47] zac at sprackett dot com

Hi Pollita,

We're running the IUS package of 5.6.30
(https://github.com/iuscommunity-pkg/php56u/blob/master/SPECS/php56u.spec) and are seeing the
following backtrace:



(gdb) bt
#0 lex_scan (zendlval=0x7ffcfe165598) at Zend/zend_language_scanner.c:1082
#1 0x00000000005c57e0 in zendlex (zendlval=0x7ffcfe165590)
at /usr/src/debug/php-5.6.30/Zend/zend_compile.c:6919
#2 0x00000000005ac9a3 in zendparse ()
at /usr/src/debug/php-5.6.30/Zend/zend_language_parser.c:3732
#3 0x00000000005b95f5 in compile_file (file_handle=0x7ffcfe165920,
type=<value optimized out>) at Zend/zend_language_scanner.l:586
#4 0x00000000005d96ea in dtrace_compile_file (file_handle=0x7ffcfe165920,
type=<value optimized out>)
at /usr/src/debug/php-5.6.30/Zend/zend_dtrace.c:40
#5 0x00007f9dcff71b02 in phar_compile_file (file_handle=0x7ffcfe165920,
type=2) at /usr/src/debug/php-5.6.30/ext/phar/phar.c:3370
#6 0x00000000005b8c6e in compile_filename (type=2, filename=0x83bdd78)
at Zend/zend_language_scanner.l:629
#7 0x0000000000657683 in ZEND_INCLUDE_OR_EVAL_SPEC_VAR_HANDLER (
execute_data=0x7f9de0a7abf0)
at /usr/src/debug/php-5.6.30/Zend/zend_vm_execute.h:13753
#8 0x00000000006584b8 in execute_ex (execute_data=0x7f9de0a7abf0)
at /usr/src/debug/php-5.6.30/Zend/zend_vm_execute.h:363
#9 0x00000000005d95be in dtrace_execute_ex (execute_data=0x7f9de0a7abf0)
at /usr/src/debug/php-5.6.30/Zend/zend_dtrace.c:73
#10 0x0000000000669054 in zend_do_fcall_common_helper_SPEC (
execute_data=<value optimized out>)
at /usr/src/debug/php-5.6.30/Zend/zend_vm_execute.h:592
#11 0x00000000006584b8 in execute_ex (execute_data=0x7f9de0a7a640)
at /usr/src/debug/php-5.6.30/Zend/zend_vm_execute.h:363
#12 0x00000000005d95be in dtrace_execute_ex (execute_data=0x7f9de0a7a640)
at /usr/src/debug/php-5.6.30/Zend/zend_dtrace.c:73
#13 0x0000000000669054 in zend_do_fcall_common_helper_SPEC (
execute_data=<value optimized out>)
at /usr/src/debug/php-5.6.30/Zend/zend_vm_execute.h:592
#14 0x00000000006584b8 in execute_ex (execute_data=0x7f9de0a79de0)
at /usr/src/debug/php-5.6.30/Zend/zend_vm_execute.h:363
#15 0x00000000005d95be in dtrace_execute_ex (execute_data=0x7f9de0a79de0)
at /usr/src/debug/php-5.6.30/Zend/zend_dtrace.c:73
#16 0x0000000000669054 in zend_do_fcall_common_helper_SPEC (
execute_data=<value optimized out>)
at /usr/src/debug/php-5.6.30/Zend/zend_vm_execute.h:592
#17 0x00000000006584b8 in execute_ex (execute_data=0x7f9de0a77ab0)
at /usr/src/debug/php-5.6.30/Zend/zend_vm_execute.h:363
#18 0x00000000005d95be in dtrace_execute_ex (execute_data=0x7f9de0a77ab0)
at /usr/src/debug/php-5.6.30/Zend/zend_dtrace.c:73
#19 0x0000000000669054 in zend_do_fcall_common_helper_SPEC (
execute_data=<value optimized out>)
at /usr/src/debug/php-5.6.30/Zend/zend_vm_execute.h:592
#20 0x00000000006584b8 in execute_ex (execute_data=0x7f9de0a779c0)
at /usr/src/debug/php-5.6.30/Zend/zend_vm_execute.h:363
#21 0x00000000005d95be in dtrace_execute_ex (execute_data=0x7f9de0a779c0)
at /usr/src/debug/php-5.6.30/Zend/zend_dtrace.c:73
#22 0x0000000000669054 in zend_do_fcall_common_helper_SPEC (
execute_data=<value optimized out>)
at /usr/src/debug/php-5.6.30/Zend/zend_vm_execute.h:592
#23 0x00000000006584b8 in execute_ex (execute_data=0x7f9de0a778d0)
at /usr/src/debug/php-5.6.30/Zend/zend_vm_execute.h:363
#24 0x00000000005d95be in dtrace_execute_ex (execute_data=0x7f9de0a778d0)
at /usr/src/debug/php-5.6.30/Zend/zend_dtrace.c:73
#25 0x0000000000669054 in zend_do_fcall_common_helper_SPEC (
execute_data=<value optimized out>)
at /usr/src/debug/php-5.6.30/Zend/zend_vm_execute.h:592
#26 0x00000000006584b8 in execute_ex (execute_data=0x7f9de0a777d0)
at /usr/src/debug/php-5.6.30/Zend/zend_vm_execute.h:363
#27 0x00000000005d95be in dtrace_execute_ex (execute_data=0x7f9de0a777d0)
at /usr/src/debug/php-5.6.30/Zend/zend_dtrace.c:73
#28 0x0000000000669054 in zend_do_fcall_common_helper_SPEC (
execute_data=<value optimized out>)
at /usr/src/debug/php-5.6.30/Zend/zend_vm_execute.h:592
#29 0x00000000006584b8 in execute_ex (execute_data=0x7f9de0a775e8)
at /usr/src/debug/php-5.6.30/Zend/zend_vm_execute.h:363
#30 0x00000000005d95be in dtrace_execute_ex (execute_data=0x7f9de0a775e8)
at /usr/src/debug/php-5.6.30/Zend/zend_dtrace.c:73
#31 0x0000000000669054 in zend_do_fcall_common_helper_SPEC (
execute_data=<value optimized out>)
at /usr/src/debug/php-5.6.30/Zend/zend_vm_execute.h:592
#32 0x00000000006584b8 in execute_ex (execute_data=0x7f9de0a76800)
at /usr/src/debug/php-5.6.30/Zend/zend_vm_execute.h:363
#33 0x00000000005d95be in dtrace_execute_ex (execute_data=0x7f9de0a76800)
at /usr/src/debug/php-5.6.30/Zend/zend_dtrace.c:73
#34 0x0000000000669054 in zend_do_fcall_common_helper_SPEC (
execute_data=<value optimized out>)
at /usr/src/debug/php-5.6.30/Zend/zend_vm_execute.h:592
#35 0x00000000006584b8 in execute_ex (execute_data=0x7f9de0a76220)
at /usr/src/debug/php-5.6.30/Zend/zend_vm_execute.h:363
#36 0x00000000005d95be in dtrace_execute_ex (execute_data=0x7f9de0a76220)
at /usr/src/debug/php-5.6.30/Zend/zend_dtrace.c:73
#37 0x00000000006583c9 in ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER (
execute_data=0x7f9de0a745e8)
at /usr/src/debug/php-5.6.30/Zend/zend_vm_execute.h:3026
#38 0x00000000006584b8 in execute_ex (execute_data=0x7f9de0a745e8)
at /usr/src/debug/php-5.6.30/Zend/zend_vm_execute.h:363
#39 0x00000000005d95be in dtrace_execute_ex (execute_data=0x7f9de0a745e8)
at /usr/src/debug/php-5.6.30/Zend/zend_dtrace.c:73
#40 0x0000000000669054 in zend_do_fcall_common_helper_SPEC (
execute_data=<value optimized out>)
at /usr/src/debug/php-5.6.30/Zend/zend_vm_execute.h:592
#41 0x00000000006584b8 in execute_ex (execute_data=0x7f9de0a74278)
at /usr/src/debug/php-5.6.30/Zend/zend_vm_execute.h:363
#42 0x00000000005d95be in dtrace_execute_ex (execute_data=0x7f9de0a74278)
at /usr/src/debug/php-5.6.30/Zend/zend_dtrace.c:73
#43 0x0000000000669054 in zend_do_fcall_common_helper_SPEC (
execute_data=<value optimized out>)
at /usr/src/debug/php-5.6.30/Zend/zend_vm_execute.h:592
#44 0x00000000006584b8 in execute_ex (execute_data=0x7f9de0a73418)
at /usr/src/debug/php-5.6.30/Zend/zend_vm_execute.h:363
#45 0x00000000005d95be in dtrace_execute_ex (execute_data=0x7f9de0a73418)
at /usr/src/debug/php-5.6.30/Zend/zend_dtrace.c:73
#46 0x0000000000669054 in zend_do_fcall_common_helper_SPEC (
execute_data=<value optimized out>)
at /usr/src/debug/php-5.6.30/Zend/zend_vm_execute.h:592
#47 0x00000000006584b8 in execute_ex (execute_data=0x7f9de0a72bf8)
at /usr/src/debug/php-5.6.30/Zend/zend_vm_execute.h:363
#48 0x00000000005d95be in dtrace_execute_ex (execute_data=0x7f9de0a72bf8)
at /usr/src/debug/php-5.6.30/Zend/zend_dtrace.c:73
#49 0x0000000000669054 in zend_do_fcall_common_helper_SPEC (
execute_data=<value optimized out>)
at /usr/src/debug/php-5.6.30/Zend/zend_vm_execute.h:592
#50 0x00000000006584b8 in execute_ex (execute_data=0x7f9de0a725a0)
at /usr/src/debug/php-5.6.30/Zend/zend_vm_execute.h:363
#51 0x00000000005d95be in dtrace_execute_ex (execute_data=0x7f9de0a725a0)
at /usr/src/debug/php-5.6.30/Zend/zend_dtrace.c:73
#52 0x0000000000669054 in zend_do_fcall_common_helper_SPEC (
execute_data=<value optimized out>)
at /usr/src/debug/php-5.6.30/Zend/zend_vm_execute.h:592
#53 0x00000000006584b8 in execute_ex (execute_data=0x7f9de0a71250)
at /usr/src/debug/php-5.6.30/Zend/zend_vm_execute.h:363
#54 0x00000000005d95be in dtrace_execute_ex (execute_data=0x7f9de0a71250)
at /usr/src/debug/php-5.6.30/Zend/zend_dtrace.c:73
#55 0x0000000000669054 in zend_do_fcall_common_helper_SPEC (
execute_data=<value optimized out>)
at /usr/src/debug/php-5.6.30/Zend/zend_vm_execute.h:592
#56 0x00000000006584b8 in execute_ex (execute_data=0x7f9de0a70f78)
at /usr/src/debug/php-5.6.30/Zend/zend_vm_execute.h:363
#57 0x00000000005d95be in dtrace_execute_ex (execute_data=0x7f9de0a70f78)
at /usr/src/debug/php-5.6.30/Zend/zend_dtrace.c:73
#58 0x0000000000669054 in zend_do_fcall_common_helper_SPEC (
execute_data=<value optimized out>)
at /usr/src/debug/php-5.6.30/Zend/zend_vm_execute.h:592
#59 0x00000000006584b8 in execute_ex (execute_data=0x7f9de0a70898)
at /usr/src/debug/php-5.6.30/Zend/zend_vm_execute.h:363
#60 0x00000000005d95be in dtrace_execute_ex (execute_data=0x7f9de0a70898)
at /usr/src/debug/php-5.6.30/Zend/zend_dtrace.c:73
#61 0x00000000005e8d6c in zend_execute_scripts (type=8, retval=0x0,
file_count=2) at /usr/src/debug/php-5.6.30/Zend/zend.c:1341
#62 0x0000000000586965 in php_execute_script (primary_file=0x7ffcfe169ea0)
at /usr/src/debug/php-5.6.30/main/main.c:2610
#63 0x0000000000690b86 in do_cli (argc=11, argv=0x2335510)
at /usr/src/debug/php-5.6.30/sapi/cli/php_cli.c:998
#64 0x0000000000691318 in main (argc=11, argv=0x2335510)
at /usr/src/debug/php-5.6.30/sapi/cli/php_cli.c:1382

------------------------------------------------------------------------


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=52752


--
Edit this bug report at https://bugs.php.net/bug.php?id=52752&edit=1


Thread (44 messages)

« previous php.bugs (#209622) next »