From: Dmitry Stogov Date: Wed, 24 Feb 2016 20:46:11 +0000 (+0300) Subject: Fixed possible crash at PCRE on MSHUTDOWN X-Git-Tag: php-7.0.5RC1~63 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6842a3674d8eadf9fac40411d21dd8b015e132f5;p=php Fixed possible crash at PCRE on MSHUTDOWN --- diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index cd91dfbc4b..48b8d6a682 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -1992,7 +1992,7 @@ static void accel_reset_pcre_cache(void) ZEND_HASH_FOREACH_BUCKET(&PCRE_G(pcre_cache), p) { /* Remove PCRE cache entries with inconsistent keys */ - if (ZSTR_IS_INTERNED(p->key)) { + if (zend_accel_in_shm(p->key)) { p->key = NULL; zend_hash_del_bucket(&PCRE_G(pcre_cache), p); } diff --git a/ext/opcache/zend_file_cache.c b/ext/opcache/zend_file_cache.c index b65abca225..3187412423 100644 --- a/ext/opcache/zend_file_cache.c +++ b/ext/opcache/zend_file_cache.c @@ -132,8 +132,13 @@ static int zend_file_cache_flock(int fd, int type) } else { \ ZEND_ASSERT(IS_SERIALIZED(ptr)); \ (ptr) = (void*)((char*)buf + (size_t)(ptr)); \ - GC_FLAGS(ptr) |= IS_STR_INTERNED; \ - GC_FLAGS(ptr) &= ~IS_STR_PERMANENT; \ + /* script->corrupted shows if the script in SHM or not */ \ + if (EXPECTED(!script->corrupted)) { \ + GC_FLAGS(ptr) |= IS_STR_INTERNED | IS_STR_PERMANENT; \ + } else { \ + GC_FLAGS(ptr) |= IS_STR_INTERNED; \ + GC_FLAGS(ptr) &= ~IS_STR_PERMANENT; \ + } \ } \ } \ } while (0) @@ -223,8 +228,7 @@ static void *zend_file_cache_unserialize_interned(zend_string *str, int in_shm) ret = accel_new_interned_string(str); if (ret == str) { /* String wasn't interned but we will use it as interned anyway */ - GC_FLAGS(ret) |= IS_STR_INTERNED; - GC_FLAGS(ret) &= ~IS_STR_PERMANENT; + GC_FLAGS(ret) |= IS_STR_INTERNED | IS_STR_PERMANENT; } } else { ret = str; diff --git a/ext/opcache/zend_shared_alloc.c b/ext/opcache/zend_shared_alloc.c index d616c7d62f..6625fe23c3 100644 --- a/ext/opcache/zend_shared_alloc.c +++ b/ext/opcache/zend_shared_alloc.c @@ -507,3 +507,16 @@ void zend_accel_shared_protect(int mode) } #endif } + +int zend_accel_in_shm(void *ptr) +{ + int i; + + for (i = 0; i < ZSMMG(shared_segments_count); i++) { + if ((char*)ptr >= (char*)ZSMMG(shared_segments)[i]->p && + (char*)ptr < (char*)ZSMMG(shared_segments)[i]->p + ZSMMG(shared_segments)[i]->size) { + return 1; + } + } + return 0; +} diff --git a/ext/opcache/zend_shared_alloc.h b/ext/opcache/zend_shared_alloc.h index 3993b0689e..03b82d16ac 100644 --- a/ext/opcache/zend_shared_alloc.h +++ b/ext/opcache/zend_shared_alloc.h @@ -128,6 +128,8 @@ void *zend_shared_alloc(size_t size); void *_zend_shared_memdup(void *p, size_t size, zend_bool free_source); int zend_shared_memdup_size(void *p, size_t size); +int zend_accel_in_shm(void *ptr); + typedef union _align_test { void *ptr; double dbl;