diff options
Diffstat (limited to 'bug75579.patch')
-rw-r--r-- | bug75579.patch | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/bug75579.patch b/bug75579.patch new file mode 100644 index 0000000..f69c853 --- /dev/null +++ b/bug75579.patch @@ -0,0 +1,76 @@ +From 841e7a192259e3e8ec34645176a2f4565e7e8877 Mon Sep 17 00:00:00 2001 +From: Dmitry Stogov <dmitry@zend.com> +Date: Thu, 21 Dec 2017 23:34:21 +0300 +Subject: [PATCH] Fixed bug #75579 (Interned strings buffer overflow may cause + crash) + +--- + NEWS | 4 ++++ + ext/opcache/zend_file_cache.c | 32 ++++++++++++++++++++++++++++++-- + 2 files changed, 34 insertions(+), 2 deletions(-) + +diff --git a/ext/opcache/zend_file_cache.c b/ext/opcache/zend_file_cache.c +index fb6827a9fd70..344851ec44a2 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; +@@ -1303,6 +1312,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; +@@ -1395,6 +1405,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(); +@@ -1444,7 +1455,24 @@ zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handl + 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) { |