Bug #66429 [Opn->Csd]: Logic flaw in handling of empty Interned strings

From: Date: Tue, 07 Jan 2014 15:56:06 +0000
Subject: Bug #66429 [Opn->Csd]: Logic flaw in handling of empty Interned strings
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-183628@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=66429&edit=1 ID: 66429 User updated by: Terry at ellisons dot org dot uk Reported by: Terry at ellisons dot org dot uk Summary: Logic flaw in handling of empty Interned strings -Status: Open +Status: Closed Type: Bug Package: opcache Operating System: N/A PHP Version: master-Git-2014-01-06 (Git) Block user comment: N Private report: N New Comment: Sorry, I've just realised that I've missed some PHP-5.6 changes in ext/opcache -- including this specific fix. I suppose that at least I came up with the same change after some blundering around ;-( As a general note (that I also made As I commented in https://github.com/zendtech/ZendOptimizerPlus/issues/157, the code bases for ext/opcache and http://pecl.php.net/package/ZendOpcache should be identical, and hence these PHP-5.6-specifc changes to ext/opcache should be guarded by a #if ZEND_EXTENSION_API_NO > PHP_5_5_X_API_NO test and they currently aren't. Previous Comments: ------------------------------------------------------------------------ [2014-01-07 00:07:19] Terry at ellisons dot org dot uk Sorry, I've just tested this on 5.5 and realised that I need #if ZEND_EXTENSION_API_NO >= PHP_5_5_X_API_NO ... #endif around my references to interned_empty_string. I'll post an updated patch tomorrow. ------------------------------------------------------------------------ [2014-01-06 23:27:17] Terry at ellisons dot org dot uk Description: ------------ The opcache extenstion turns off PHP string interning and substitutes its own strategy for collecting interned strings in its own SHM-based interned_strings hash during in ZendAcclerator.c:zend_accel_init_shm(). It is then turned off in accel_shutdown(). Before and after these points in accel_startup() and accel_shutdown(), all interned strings created and dtored should lie between the original CG(interned_strings_start) and CG(interned_strings_end). Note that this list of local interned strings is non-trivial (typically some 2,000) comprising interned_string representations of all builtin Zend and extension constants, function names and methods. I call these built-in interned strings. Between these same points all interned strings created and dtored should lie between ZCSG(interned_strings_start) and ZCSG(interned_strings_end). I call these shared interned strings. However, if a zval refering to a builtin interned string is dtored between accel_startup() and accel_shutdown(), then the !IS_INTERNED() macro will return false as the address of the string lies between original CG(interned_strings_start) and CG(interned_strings_end) and not between ZCSG(interned_strings_start) and ZCSG(interned_strings_end). DTOR will then attempt to efree the string which is invalid as the string wasn't emalloc'ed. As long as the scope and lifetimes of the two sets of interned strings are disjoint this all works fine. However, one optimization introduced in PHP-5.6 has been missed and that is with strings and zvals created with the STR_EMPTY_ALLOC(), RETVAL_EMPTY_STRING() and ZVAL_EMPTY_STRING() macros. These are all based on the CG(interned_empty_string) value and this is a built-in interned string. If any of these are DTORed then the dtor will fail as described above. ZendAccelerator should establish its own ZCSG(interned_empty_string) value to prevent this happening. Test script: --------------- php56 -r '' (with opcache enabled) ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=66429&edit=1

« previous php.bugs (#183628) next »