Cphalcon: 3.4.3 segfaults with PHP 7.3.6 (but not 7.3.5) and OPcache

Created on 5 Jun 2019  ·  31Comments  ·  Source: phalcon/cphalcon

Having cphalcon 3.4.3 enabled in PHP 7.3.6 together with OPcache leads to a segmentation fault somewhere during engine or request shutdown - scripts etc run fine, but PHP segfaults before exiting:

$ php -v
PHP 7.3.6 (cli) (built: May 30 2019 14:55:18) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.6, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.3.6, Copyright (c) 1999-2018, by Zend Technologies
Segmentation fault

Disabling phalcon, or disabling opache, fixes the issue.

The crash does not occur on 7.3.5, which makes me think it's related to OPcache changes in 7.3.6 the changelog describes as "fixed possible crashes, because of inconsistent PCRE cache and opcache SHM reset."

I can't rebuild everything as debug builds at the moment and provide core dumps etc, so I'm hoping y'all can reproduce and diagnose this more easily than me.

Details

$ php --ri phalcon

phalcon

Web framework delivered as a C-extension for PHP
phalcon => enabled
Author => Phalcon Team and contributors
Version => 3.4.3
Build Date => Mar  8 2019 15:07:32
Powered by Zephir => Version 0.10.14-975ad02db4

Directive => Local Value => Master Value
phalcon.db.escape_identifiers => On => On
phalcon.db.force_casting => Off => Off
phalcon.orm.events => On => On
phalcon.orm.virtual_foreign_keys => On => On
phalcon.orm.column_renaming => On => On
phalcon.orm.not_null_validations => On => On
phalcon.orm.exception_on_failed_save => Off => Off
phalcon.orm.enable_literals => On => On
phalcon.orm.late_state_binding => Off => Off
phalcon.orm.enable_implicit_joins => On => On
phalcon.orm.cast_on_hydrate => Off => Off
phalcon.orm.ignore_unknown_columns => Off => Off
phalcon.orm.update_snapshot_on_save => On => On
phalcon.orm.disable_assign_setters => Off => Off
Segmentation fault
$ php -i
phpinfo()
PHP Version => 7.3.6

System => Linux f94a1774-dc9b-47b5-b3bf-6b2007d6deb8 4.4.0-1044-aws #47-Ubuntu SMP Wed May 8 19:02:36 UTC 2019 x86_64
Build Date => May 30 2019 14:52:51
Configure Command =>  './configure'  '--prefix=/app/.heroku/php' '--with-config-file-path=/app/.heroku/php/etc/php' '--with-config-file-scan-dir=/app/.heroku/php/etc/php/conf.d' '--disable-phpdbg' '--enable-fpm' '--with-bz2' '--with-curl' '--with-pdo-mysql' '--with-mysqli' '--with-openssl' '--with-kerberos' '--with-pgsql' '--with-pdo-pgsql' '--with-readline' '--enable-sockets' '--enable-zip' '--with-zlib' '--enable-bcmath=shared' '--enable-calendar=shared' '--enable-exif=shared' '--enable-ftp=shared' '--with-gd=shared' '--with-freetype-dir=/usr' '--with-jpeg-dir=/usr' '--with-png-dir=/usr' '--with-gettext=shared' '--with-gmp=shared' '--with-imap=shared,/app/.heroku/php/opt/imap-2007f' '--with-imap-ssl' '--enable-intl=shared' '--with-ldap=shared' '--with-ldap-sasl' '--enable-mbstring=shared' '--enable-pcntl=shared' '--enable-shmop=shared' '--enable-soap=shared' '--with-sqlite3=shared' '--with-pdo-sqlite=shared' '--with-xmlrpc=shared' '--with-xsl=shared' '--enable-opcache-file' '--without-libzip' '--with-sodium=shared'
Server API => Command Line Interface
Virtual Directory Support => disabled
Configuration File (php.ini) Path => /app/.heroku/php/etc/php
Loaded Configuration File => /app/.heroku/php/etc/php/php.ini
Scan this dir for additional .ini files => /app/.heroku/php/etc/php/conf.d
Additional .ini files parsed => /app/.heroku/php/etc/php/conf.d/000-heroku.ini,
/app/.heroku/php/etc/php/conf.d/010-ext-zend_opcache.ini,
/app/.heroku/php/etc/php/conf.d/100-ext-bcmath.ini,
/app/.heroku/php/etc/php/conf.d/110-ext-calendar.ini,
/app/.heroku/php/etc/php/conf.d/120-ext-intl.ini,
/app/.heroku/php/etc/php/conf.d/130-ext-mbstring.ini,
/app/.heroku/php/etc/php/conf.d/140-ext-xmlrpc.ini,
/app/.heroku/php/etc/php/conf.d/150-ext-phalcon.ini,
/app/.heroku/php/etc/php/conf.d/160-ext-redis.ini
…
Segmentation fault

Most helpful comment

Phalcon v3.4.4 was released.

All 31 comments

@dreamsxin could you check it? Im guessing that any extension on zephir can cause this since php --ri phalcon is enough to cause seg fault.

Also adding a core dump would help @dzuelke

Alright, core dump:

# php -d"extension=phalcon.so" --ri phalcon

phalcon

…

php: /tmp/bob-aEolPN/php-7.3.6/ext/opcache/ZendAccelerator.c:743: accel_replace_string_by_process_permanent: Assertion `!((char*)(str) >= (char*)(accel_shared_globals->interned_strings).start && (char*)(str) < (char*)(accel_shared_globals->interned_strings).top)' failed.
Aborted (core dumped)
# gdb $(which php) core
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /app/.heroku/php/bin/php...done.
[New LWP 70485]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `php -dextension=phalcon.so --ri phalcon'.
Program terminated with signal SIGABRT, Aborted.
#0  0x00007f2846204428 in __GI_raise (sig=sig@entry=6)
    at ../sysdeps/unix/sysv/linux/raise.c:54
54  ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) bt
#0  0x00007f2846204428 in __GI_raise (sig=sig@entry=6)
    at ../sysdeps/unix/sysv/linux/raise.c:54
#1  0x00007f284620602a in __GI_abort () at abort.c:89
#2  0x00007f28461fcbd7 in __assert_fail_base (fmt=<optimized out>, 
    assertion=assertion@entry=0x7f283edcf820 "!((char*)(str) >= (char*)(accel_shared_globals->interned_strings).start && (char*)(str) < (char*)(accel_shared_globals->interned_strings).top)", 
    file=file@entry=0x7f283edcf7e8 "/tmp/bob-aEolPN/php-7.3.6/ext/opcache/ZendAccelerator.c", line=line@entry=743, 
    function=function@entry=0x7f283edcff20 <__PRETTY_FUNCTION__.19051> "accel_replace_string_by_process_permanent") at assert.c:92
#3  0x00007f28461fcc82 in __GI___assert_fail (
    assertion=0x7f283edcf820 "!((char*)(str) >= (char*)(accel_shared_globals->interned_strings).start && (char*)(str) < (char*)(accel_shared_globals->interned_strings).top)", 
    file=0x7f283edcf7e8 "/tmp/bob-aEolPN/php-7.3.6/ext/opcache/ZendAccelerator.c", line=743, 
    function=0x7f283edcff20 <__PRETTY_FUNCTION__.19051> "accel_replace_string_by_process_permanent") at assert.c:101
#4  0x00007f283ed3f731 in accel_replace_string_by_process_permanent (
    str=0x7f28367cb210)
    at /tmp/bob-aEolPN/php-7.3.6/ext/opcache/ZendAccelerator.c:743
#5  0x00007f283ed3eef1 in accel_copy_permanent_strings (
---Type <return> to continue, or q <return> to quit---
    new_interned_string=0x7f283ed3f6b5 <accel_replace_string_by_process_permanent>) at /tmp/bob-aEolPN/php-7.3.6/ext/opcache/ZendAccelerator.c:646
#6  0x00007f283ed3f800 in accel_use_permanent_interned_strings ()
    at /tmp/bob-aEolPN/php-7.3.6/ext/opcache/ZendAccelerator.c:771
#7  0x00000000009e4014 in zend_interned_strings_switch_storage (
    request=0 '\000') at /tmp/bob-aEolPN/php-7.3.6/Zend/zend_string.c:336
#8  0x000000000090b9a1 in php_module_shutdown ()
    at /tmp/bob-aEolPN/php-7.3.6/main/main.c:2473
#9  0x0000000000a85bfc in main (argc=4, argv=0x325e070)
    at /tmp/bob-aEolPN/php-7.3.6/sapi/cli/php_cli.c:1404

Also submitted to bugs.php.net for good measure: https://bugs.php.net/bug.php?id=78121, but no idea if the cause is on the phalcon or the PHP side...

diff --git a/ext/kernel/main.c b/ext/kernel/main.c
index c940e0e26..c14e24a36 100644
--- a/ext/kernel/main.c
+++ b/ext/kernel/main.c
@@ -389,10 +389,20 @@ int zephir_declare_class_constant(zend_class_entry *ce, const char *name, size_t
 {
 #if PHP_VERSION_ID >= 70100
        int ret;
+       zend_string *key;
+
+       if (ce->type == ZEND_INTERNAL_CLASS) {
+               key = zend_string_init_interned(name, name_length, 1);
+       } else {
+               key = zend_string_init(name, name_length, 0);
+       }

-       zend_string *key = zend_string_init(name, name_length, ce->type & ZEND_INTERNAL_CLASS);
        ret = zend_declare_class_constant_ex(ce, key, value, ZEND_ACC_PUBLIC, NULL);
-       zend_string_release(key);
+
+       if (ce->type != ZEND_INTERNAL_CLASS) {
+               zend_string_release(key);
+       }
+
        return ret;
 #else
        if (Z_CONSTANT_P(value)) {

@sergeyklay or @Jurigag, is there any chance you could roll a 3.4.4 bugfix release with those Zephir updates soon? We've got Phalcon customers getting segfaults with the latest PHP 7.3.6 release on Heroku, and 7.3.5 has open CVEs.

This will require to backport this fix to zephir 0.10.x as well because phalcon 3.4 is not compatible with zephir 0.11.x. What i could suggest is that you could maybe cherry pick this fix to 0.10.x zephir branch compile extension yourself and provide them to customers, though not sure if it's possible for you.

Of course that's possible, but the issue isn't specific to Heroku.

Any user of Phalcon will run into this once they upgrade to PHP 7.3.6 or 7.2.19, which both contain security fixes.

And given how a stable release of Phalcon 4 is probably still quite some time away, a 3.4 bugfix release makes sense, no?

@niden

May I suggest re-opening this issue until a release is cut, so that other people find it more easily? Right now it's fixed, but not really - the fix has been merged into Zephir, but no release has been cut for that or for Phalcon...

Thanks for the reopen @Jurigag.

What are the steps for updating Zephir by hand, regenerating the extension, and regenerating the build? There are a few instructions somewhere for how to regenerate the build when working on *.zep files in this repo, but nothing at all on how to update Zephir.

Is all the code just copied over into this repo? Or is there a process? I couldn't find anything about that.

Got it; for those interested:

git clone https://github.com/phalcon/php-zephir-parser
pushd php-zephir-parser
phpize
./configure --prefix=…
make -s -j9
make install -s
echo "extension=zephir_parser.so" >> …/etc/php/conf.d/zehpir.ini
popd
git clone https://github.com/phalcon/zephir
pushd zephir
git checkout 0.10.x
./install-nosudo
popd
zephir/bin/zephir generate --backend=ZendEngine3
php build/gen-build.php

Then install as usual, from build/php7/safe.

+1 for 3.4.4 with this fix

I'll regenerate the build for 3.4.x in next days. Could someone ping me if I forget to do this

Will follow up as needed ... thanks @sergeyklay

Ping @sergeyklay -- Just ran into this myself not connecting the dots (See above issue reference) (Thought the issue was on Fedora side). When you get chance to make 3.4.4 would be awesome to confirm this is resolved.

I apologize @dzuelke for completely overlooking this.

Just regenerated C-code for Phalcon's 3.4.x branch:

* 4d7e9a9f6 | Thu Jun 27 22:08:30 2019 | Bump version (HEAD -> 3.4.x, origin/3.4.x) [Serghei Iakovlev]
* 0316216d2 | Thu Jun 27 22:07:19 2019 | Regenerated build (PHP7) [Serghei Iakovlev]
* 9d4a4af02 | Thu Jun 27 22:01:11 2019 | Regenerated build (PHP5) [Serghei Iakovlev]
* b517269a9 | Thu Jun 27 22:00:36 2019 | Use latest Zephir from 0.10.x branch [Serghei Iakovlev]

You can try new Phalcon using command as follows:

$ git clone --depth=1 --branch=3.4.x https://github.com/phalcon/cphalcon.git
$ cd cphalcon/build
$ sudo ./install

# If you have specific php versions running
$ sudo ./install --phpize /usr/bin/phpize5.6 --php-config /usr/bin/php-config5.6

Thanks for catching this bug, and I am sorry about the delay. I hope it fixed now. I'm closing this issue but if I have made an oversight, please do get back in touch.

I would appreciate if somebody could please provide a windows recompiled x64 dll, if I missed an official dl link.
Thx in advance

@sergeyklay Can we create 3.4.4 release + builds?

The 3.x branch is not longer supported (it was LTS). Nevertheless, I prepared everything you might needed to install Phalcon using 1 simple command.

That doesn't make any sense. If it's supported long term .. we need this fix. Currently 3.4.3 is broken with latest PHP .. LTS can make point builds all the time ... just cut a new release. and rebuild so packagecloud is updated and then ondrej's PPAs will update and same with Remi's.

Don't forget the windows builds, please. I personally cannot compile in windows myself, because I cannot install visual studio (restricted corporate firewall policy, as well as the decision to use windows at all) .. I just can't do anything about it) and I just need to use phalcon without the build process. That would mean we are stuck on 7.3.5. Try to explain this to our customers security officer...
Again, I appreciate if _anybody_ could provide windows x64 builds

The 3.x branch is not longer supported (it was LTS).

How is it possible ?
3.4.3 is the LATEST released version.

And until 4.0 is any kind of proven stable final (no alpha, no beta) there is no other official running and supported version than 3.4.3 at the moment which people (at least serious managers) will approve for usage in a production environment.
That said, if no 3.4.x version is officially provided having this fixed for the latest php version, I smell people saying to abandon phalcon and go back to a raw php framework again. (we had the dicussion before some months ago and it was a very good decision by you to, in the end, officially provide 3.4.3 for all platforms back then 👍🏻)
Phalcon 4.x stable final will still take many more months I guess, and that cannot mean you want your users being stuck at old php versions or force them to use either 4. 0 alpha/beta versions (which require adjusting of their code anyway) or compile the stuff on their own (and unfortunately there are not only Linux and Mac users)
Please take a deep breath and think about it again 🙂 thank you 😉

We will sort this out this weekend - try to build DLLs also.

It was our mistake that we did not add the LTS note and duration in the documentation in its own page so that all can refer to that. Our announcement was 3 years LTS for the v3 which is en par or more than the average LTS of packages.

Having written that, 3 years have passed, Just because something is LTS does not mean that it is maintained forever. For the argument _well there is no v4 to upgrade_, that is evident. My point is just because a new version has not been released yet, does not necessarily mean that the LTS time defined will be extended indefinitely or otherwise.

Just a few thoughts.

Thanks Niden ... all we need is just a 3.4.4 release - it's super easy and just allows for downstream maintainers to properly build packages. Code, I believe, is already merged. So just tag/release and run appropriate release stuff.

Agreed.

Just a heads up team - Based on the complete lack of features and the massive amount of code churn in 4.x, we have absolutely no intentions on upgrading.

Same @david-duncan

If the timeline for 4.x has shifted since the LTS announcement was made, then maybe the LTS timeline should also be adjusted accordingly.

I understand the desire to not have too much code to maintain in parallel, but the fact is that right now, the latest stable release does not work on the latest stable PHP version, which contains security fixes.

And IMHO, even if 4.x had been released recently, a 3.4.4 would still be necessary. Users can't simply upgrade to a major new framework version overnight. This sort of predictability and reliability is important for a framework; otherwise, people can't rely on it, if they have to risk the foundation of their projects to become abandonware without a suitable replacement.

For 4.x, I propose the LTS strategy to be something like "bug fixes for six months after 5.0.0 is released, security fixes for another six months after that", or similar.

And of course, I can simply rebuild Phalcon/Zephir from source (already did that two weeks ago and rolled it out on Heroku; https://devcenter.heroku.com/changelog-items/1651), but as a downstream maintainer, I want to provide standard package releases to users, not custom builds with a bunch of patches on top.

Phalcon v3.4.4 was released.

Was this page helpful?
0 / 5 - 0 ratings