Bug #52752 [Com]: Crash when lexing

From: Date: Sun, 25 Jun 2017 23:46:48 +0000
Subject: Bug #52752 [Com]: Crash when lexing
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-209680@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: Patch for php 5.6.30 is here: https://gist.github.com/zsprackett/8197f0242040c2e43d8d800521f09e22 Previous Comments: ------------------------------------------------------------------------ [2017-06-21 17:56:27] zac at sprackett dot com 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) { ------------------------------------------------------------------------ [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

« previous php.bugs (#209680) next »