diff options
author | Dmitry Stogov <dmitry@zend.com> | 2017-12-21 23:35:23 +0300 |
---|---|---|
committer | Dmitry Stogov <dmitry@zend.com> | 2017-12-21 23:35:23 +0300 |
commit | f2c22d11cc416e817549c66f1305157d3fefebe8 (patch) | |
tree | 879cbd74c156375ced3e451708c005abe4cbe885 | |
parent | cc5a0da006205daaf1b01f41aaca942f5f6609b8 (diff) | |
parent | 37bf8bdc1494abb2ce5cac40e0be80e23682f851 (diff) | |
download | php-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-- | NEWS | 4 | ||||
-rw-r--r-- | ext/opcache/zend_file_cache.c | 32 |
2 files changed, 34 insertions, 2 deletions
@@ -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) { |