summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2017-12-21 23:35:23 +0300
committerDmitry Stogov <dmitry@zend.com>2017-12-21 23:35:23 +0300
commitf2c22d11cc416e817549c66f1305157d3fefebe8 (patch)
tree879cbd74c156375ced3e451708c005abe4cbe885
parentcc5a0da006205daaf1b01f41aaca942f5f6609b8 (diff)
parent37bf8bdc1494abb2ce5cac40e0be80e23682f851 (diff)
downloadphp-git-f2c22d11cc416e817549c66f1305157d3fefebe8.tar.gz
Merge branch 'PHP-7.0' into PHP-7.1
* PHP-7.0: Fixed bug #75579 (Interned strings buffer overflow may cause crash)
-rw-r--r--NEWS4
-rw-r--r--ext/opcache/zend_file_cache.c32
2 files changed, 34 insertions, 2 deletions
diff --git a/NEWS b/NEWS
index c990615010..0b3cd7e5b2 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,10 @@ PHP NEWS
- Core:
. Fixed bug #75679 (Path 260 character problem). (Anatol)
+- Opcache:
+ . Fixed bug #75579 (Interned strings buffer overflow may cause crash).
+ (Dmitry)
+
- PGSQL:
. Fixed bug #75671 (pg_version() crashes when called on a connection to
cockroach). (magicaltux at gmail dot com)
diff --git a/ext/opcache/zend_file_cache.c b/ext/opcache/zend_file_cache.c
index dea427fcaf..89b5ee62f1 100644
--- a/ext/opcache/zend_file_cache.c
+++ b/ext/opcache/zend_file_cache.c
@@ -227,8 +227,17 @@ static void *zend_file_cache_unserialize_interned(zend_string *str, int in_shm)
if (in_shm) {
ret = accel_new_interned_string(str);
if (ret == str) {
+ /* We have to create new SHM allocated string */
+ size_t size = _ZSTR_STRUCT_SIZE(ZSTR_LEN(str));
+ ret = zend_shared_alloc(size);
+ if (!ret) {
+ zend_accel_schedule_restart_if_necessary(ACCEL_RESTART_OOM);
+ LONGJMP(*EG(bailout), FAILURE);
+ }
+ memcpy(ret, str, size);
/* String wasn't interned but we will use it as interned anyway */
- GC_FLAGS(ret) |= IS_STR_INTERNED | IS_STR_PERMANENT;
+ GC_REFCOUNT(ret) = 1;
+ GC_TYPE_INFO(ret) = IS_STRING | ((IS_STR_INTERNED | IS_STR_PERSISTENT | IS_STR_PERMANENT) << 8);
}
} else {
ret = str;
@@ -1288,6 +1297,7 @@ zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handl
zend_accel_hash_entry *bucket;
void *mem, *checkpoint, *buf;
int cache_it = 1;
+ int ok;
if (!full_path) {
return NULL;
@@ -1380,6 +1390,7 @@ zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handl
if (!ZCG(accel_directives).file_cache_only &&
!ZCSG(restart_in_progress) &&
+ !ZSMMG(memory_exhausted) &&
accelerator_shm_read_lock() == SUCCESS) {
/* exclusive lock */
zend_shared_alloc_lock();
@@ -1429,7 +1440,24 @@ use_process_mem:
ZCG(mem) = ((char*)mem + info.mem_size);
script = (zend_persistent_script*)((char*)buf + info.script_offset);
script->corrupted = !cache_it; /* used to check if script restored to SHM or process memory */
- zend_file_cache_unserialize(script, buf);
+
+ ok = 1;
+ zend_try {
+ zend_file_cache_unserialize(script, buf);
+ } zend_catch {
+ ok = 0;
+ } zend_end_try();
+ if (!ok) {
+ if (cache_it) {
+ zend_shared_alloc_unlock();
+ goto use_process_mem;
+ } else {
+ zend_arena_release(&CG(arena), checkpoint);
+ efree(filename);
+ return NULL;
+ }
+ }
+
script->corrupted = 0;
if (cache_it) {