diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2018-04-27 16:58:30 +0200 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2018-04-27 17:01:35 +0200 |
commit | 279ba58edbd0454d7e534e223e3538a2b0b5ff9b (patch) | |
tree | 9cf01720da7c3846f0783b749c307b451f48172f | |
parent | 2513da4b4c3e7e49bbc01757692056c3e2630145 (diff) | |
download | php-git-279ba58edbd0454d7e534e223e3538a2b0b5ff9b.tar.gz |
Fixed bug #76275
* Adjust IS_SERIALIZED() check to account for potential empty
allocations at the end of the memory region.
* Deallocate empty allocation if all try/catch elements have been
removed in the block pass (similar to what we do if all live
ranges have been eliminated).
-rw-r--r-- | NEWS | 4 | ||||
-rw-r--r-- | ext/opcache/Optimizer/block_pass.c | 5 | ||||
-rw-r--r-- | ext/opcache/tests/bug76275.phpt | 29 | ||||
-rw-r--r-- | ext/opcache/zend_file_cache.c | 4 |
4 files changed, 41 insertions, 1 deletions
@@ -6,6 +6,10 @@ PHP NEWS . Fixed bug #76075 --with-fpm-acl wrongly tries to find libacl on FreeBSD. (mgorny) +- Opcache: + . Fixed bug #76275 (Assertion failure in file cache when unserializing empty + try_catch_array). (Nikita) + - Reflection: . Fixed arginfo for array_replace(_recursive) and array_merge(_recursive). (carusogabriel) diff --git a/ext/opcache/Optimizer/block_pass.c b/ext/opcache/Optimizer/block_pass.c index 631798ec1b..81167cea71 100644 --- a/ext/opcache/Optimizer/block_pass.c +++ b/ext/opcache/Optimizer/block_pass.c @@ -928,6 +928,11 @@ static void assemble_code_blocks(zend_cfg *cfg, zend_op_array *op_array) } if (i != j) { op_array->last_try_catch = j; + if (j == 0) { + efree(op_array->try_catch_array); + op_array->try_catch_array = NULL; + } + if (op_array->fn_flags & ZEND_ACC_HAS_FINALLY_BLOCK) { zend_op *opline = new_opcodes; zend_op *end = opline + len; diff --git a/ext/opcache/tests/bug76275.phpt b/ext/opcache/tests/bug76275.phpt new file mode 100644 index 0000000000..82e4272185 --- /dev/null +++ b/ext/opcache/tests/bug76275.phpt @@ -0,0 +1,29 @@ +--TEST-- +Bug #76275: Assertion failure in file cache when unserializing empty try_catch_array +--INI-- +opcache.enabled=1 +opcache.enable_cli=1 +opcache.file_cache=/tmp +--FILE-- +<?php + +if (PHP_VERSION_ID >= 70000) { + echo "Done"; + return; +} + +if (!is_callable('random_bytes')) { + try { + } catch (com_exception $e) { + } + + function random_bytes($length) + { + throw new Exception( + 'There is no suitable CSPRNG installed on your system' + ); + return ''; + } +} +--EXPECT-- +Done diff --git a/ext/opcache/zend_file_cache.c b/ext/opcache/zend_file_cache.c index 213028b7a1..23f2f9d0cb 100644 --- a/ext/opcache/zend_file_cache.c +++ b/ext/opcache/zend_file_cache.c @@ -96,8 +96,10 @@ static int zend_file_cache_flock(int fd, int type) #define IS_SERIALIZED_INTERNED(ptr) \ ((size_t)(ptr) & Z_UL(1)) + +/* Allowing == here to account for a potential empty allocation at the end of the memory */ #define IS_SERIALIZED(ptr) \ - ((char*)(ptr) < (char*)script->size) + ((char*)(ptr) <= (char*)script->size) #define IS_UNSERIALIZED(ptr) \ (((char*)(ptr) >= (char*)script->mem && (char*)(ptr) < (char*)script->mem + script->size) || \ IS_ACCEL_INTERNED(ptr)) |