php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #70828 php-fpm 5.6 with opcache crashes when referencing a non-existent constant
Submitted: 2015-11-01 13:44 UTC Modified: 2015-11-02 02:45 UTC
From: cf0hay at gmail dot com Assigned: laruence
Status: Closed Package: opcache
PHP Version: 5.6.15 OS: 64bit linux
Private report: No CVE-ID:
 [2015-11-01 13:44 UTC] cf0hay at gmail dot com
Description:
------------
A crash occurs when *all* of the following conditions met:

* there is a "use const" statement in a namespace
* a (static) function references that constant
* that constant haven't been defined
* the referencing function is called
* opcache is enabled
* FPM is the environmet
* php 5.6 is the version

- if there is no "use const", the old behavior works, as in it will use the constant from global namespace
- if nothing referneces the constant, it will not crash
- if the constant is defined before use, crash will not occur
- if the referncing function is not called, crash will not occur
- if opcache is *disabled*, crash not occurs (the code issues notices)
- if run from CLI, crash not occurs (the code issues notices)
- afaik php < 5.6 doesn't have this feature, and php 7.0 RC 6 is not affected, as it creates a fatal error instead, so only php 5.6 is affected

Test script:
---------------
<?php

namespace test {
    use const nonexistent;

    class test {
        static function run(){
            var_dump(nonexistent);
        }
    }
}

namespace {
    test\test::run();
}


Expected result:
----------------
PHP Notice:  Use of undefined constant nonexistent - assumed 'nonexistent'

Actual result:
--------------
Segmentation fault

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-11-01 15:07 UTC] cf0hay at gmail dot com
(gdb) bt
#0  0x00000000007940d3 in ?? ()
#1  0x0000000000794205 in zend_hash_func ()
#2  0x00007f8d41921adc in ?? () from /usr/lib64/php5.6/lib64/opcache.so
#3  0x00007f8d41928f53 in ?? () from /usr/lib64/php5.6/lib64/opcache.so
#4  0x00007f8d4192911a in ?? () from /usr/lib64/php5.6/lib64/opcache.so
#5  0x00007f8d41929364 in zend_accel_script_optimize () from /usr/lib64/php5.6/lib64/opcache.so
#6  0x00007f8d41901fab in ?? () from /usr/lib64/php5.6/lib64/opcache.so
#7  0x00007f8d41902d4c in ?? () from /usr/lib64/php5.6/lib64/opcache.so
#8  0x00007f8d419035a7 in persistent_compile_file () from /usr/lib64/php5.6/lib64/opcache.so
#9  0x0000000000783bab in zend_execute_scripts ()
#10 0x00000000006e999d in php_execute_script ()
#11 0x000000000084586e in main ()
 [2015-11-01 15:50 UTC] laruence@php.net
-Assigned To: +Assigned To: laruence
 [2015-11-01 16:29 UTC] laruence@php.net
actually, this is not a opcache issue, please verify the following fix:

diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 5ff1b04..39d6ed6 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -545,6 +545,13 @@ int zend_add_const_name_literal(zend_op_array *op_array, const zval *zv, int unq
        tmp_literal = zend_add_literal(CG(active_op_array), &c TSRMLS_CC);
        CALCULATE_LITERAL_HASH(tmp_literal);
 
+       if (unqualified && !ns_len) {
+               /* we should ensure there are five literals */
+               ZVAL_STRINGL(&c, STR_EMPTY_ALLOC(), 0, 0);
+               tmp_literal = zend_add_literal(CG(active_op_array), &c TSRMLS_CC);
+               tmp_literal = zend_add_literal(CG(active_op_array), &c TSRMLS_CC);
+       }
+
        return ret;
 }
 /* }}} */


thanks
 [2015-11-01 17:29 UTC] cf0hay at gmail dot com
Yes, ather the patch, the test code gives the proper notice, instead of a segmentation fault. Thank you!
 [2015-11-02 02:45 UTC] laruence@php.net
to prove this is not an opcache issue, please see the following test script:

<?php

namespace test {
    use const nonexistent;

    class test {
        static function run(){
            var_dump(nonexistent);
            existent;
        }
    }
}

namespace {
    define("test\\existent", "bug!", 1);
    test\test::run();
}


which will result "bug!"
 [2015-11-02 02:55 UTC] laruence@php.net
Automatic comment on behalf of laruence@gmail.com
Revision: http://git.php.net/?p=php-src.git;a=commit;h=37ed0dafe47fb1053aee7822113bacc1f213337a
Log: Fixed bug #70828 (php-fpm 5.6 with opcache crashes when referencing a non-existent constant)
 [2015-11-02 02:55 UTC] laruence@php.net
-Status: Assigned +Status: Closed
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Tue Aug 29 15:01:52 2017 UTC