diff options
author | Dmitry Stogov <dmitry@zend.com> | 2016-11-16 12:58:30 +0300 |
---|---|---|
committer | Dmitry Stogov <dmitry@zend.com> | 2016-11-16 12:58:30 +0300 |
commit | 35e7927736d98bf418084f1d8168bd45497e213a (patch) | |
tree | d2361f92972655d86ef9bfc111b17b98baa9fbe5 | |
parent | ca6091471c6aefce07319488edebcfb254944e4c (diff) | |
parent | 86460af56c520b7210d5e21afb7368d4a4d01e1d (diff) | |
download | php-git-35e7927736d98bf418084f1d8168bd45497e213a.tar.gz |
Merge branch 'PHP-7.1'
* PHP-7.1:
Fixed bug #69090 (check cached files permissions)
-rw-r--r-- | ext/opcache/README | 10 | ||||
-rw-r--r-- | ext/opcache/ZendAccelerator.c | 39 | ||||
-rw-r--r-- | ext/opcache/ZendAccelerator.h | 9 | ||||
-rw-r--r-- | ext/opcache/zend_accelerator_hash.c | 16 | ||||
-rw-r--r-- | ext/opcache/zend_accelerator_module.c | 4 |
5 files changed, 74 insertions, 4 deletions
diff --git a/ext/opcache/README b/ext/opcache/README index e4d36ba51a..cf305ad9d1 100644 --- a/ext/opcache/README +++ b/ext/opcache/README @@ -102,6 +102,16 @@ opcache.validate_timestamps (default "1") The frequency of the check is controlled by the directive "opcache.revalidate_freq". +opcache.validate_permission (default "0") + Leads OPcache to check file readability on each access to cached file. + This directive should be enabled in shared hosting environment, when few + users (PHP-FPM pools) reuse the common OPcache shared memory. + +opcache.validate_root (default "0") + This directive prevents file name collisions in different "chroot" + environments. It should be enabled for sites that may serve requests in + different "chroot" environments. + opcache.revalidate_freq (default "2") How often (in seconds) to check file timestamps for changes to the shared memory storage allocation. ("1" means validate once per second, but only diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index 2f549cc011..9b6734fb49 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -1771,6 +1771,20 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type) ZCG(counted) = 1; } + /* Revalidate acessibility of cached file */ + if (EXPECTED(persistent_script != NULL) && + UNEXPECTED(ZCG(accel_directives).validate_permission) && + file_handle->type == ZEND_HANDLE_FILENAME && + UNEXPECTED(access(file_handle->filename, R_OK) != 0)) { + if (type == ZEND_REQUIRE) { + zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, file_handle->filename TSRMLS_CC); + zend_bailout(); + } else { + zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, file_handle->filename TSRMLS_CC); + } + return NULL; + } + HANDLE_BLOCK_INTERRUPTIONS(); SHM_UNPROTECT(); @@ -2084,6 +2098,31 @@ static void accel_activate(void) } #endif +#ifndef ZEND_WIN32 + if (ZCG(accel_directives).validate_root) { + struct stat buf; + + if (stat("/", &buf) != 0) { + ZCG(root_hash) = 0; + } else { + zend_ulong x = buf.st_ino; + +#if SIZEOF_ZEND_LONG == 4 + x = ((x >> 16) ^ x) * 0x45d9f3b; + x = ((x >> 16) ^ x) * 0x45d9f3b; + x = (x >> 16) ^ x; +#elif SIZEOF_ZEND_LONG == 8 + x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; + x = (x ^ (x >> 27)) * 0x94d049bb133111eb; + x = x ^ (x >> 31); +#endif + ZCG(root_hash) = x; + } + } else { + ZCG(root_hash) = 0; + } +#endif + HANDLE_BLOCK_INTERRUPTIONS(); SHM_UNPROTECT(); diff --git a/ext/opcache/ZendAccelerator.h b/ext/opcache/ZendAccelerator.h index d45be56279..40e162926e 100644 --- a/ext/opcache/ZendAccelerator.h +++ b/ext/opcache/ZendAccelerator.h @@ -180,8 +180,10 @@ typedef struct _zend_accel_directives { zend_bool file_override_enabled; zend_bool inherited_hack; zend_bool enable_cli; - zend_ulong revalidate_freq; - zend_ulong file_update_protection; + zend_bool validate_permission; + zend_bool validate_root; + zend_ulong revalidate_freq; + zend_ulong file_update_protection; char *error_log; #ifdef ZEND_WIN32 char *mmap_base; @@ -233,6 +235,9 @@ typedef struct _zend_accel_globals { time_t last_restart_time; /* used to synchronize SHM and in-process caches */ char system_id[32]; HashTable xlat_table; +#ifndef ZEND_WIN32 + zend_ulong root_hash; +#endif /* preallocated shared-memory block to save current script */ void *mem; void *arena_mem; diff --git a/ext/opcache/zend_accelerator_hash.c b/ext/opcache/zend_accelerator_hash.c index a533d06120..7ec64cec1f 100644 --- a/ext/opcache/zend_accelerator_hash.c +++ b/ext/opcache/zend_accelerator_hash.c @@ -86,6 +86,9 @@ zend_accel_hash_entry* zend_accel_hash_update(zend_accel_hash *accel_hash, char } hash_value = zend_inline_hash_func(key, key_length); +#ifndef ZEND_WIN32 + hash_value ^= ZCG(root_hash); +#endif index = hash_value % accel_hash->max_num_entries; /* try to see if the element already exists in the hash */ @@ -139,9 +142,15 @@ zend_accel_hash_entry* zend_accel_hash_update(zend_accel_hash *accel_hash, char static zend_always_inline void* zend_accel_hash_find_ex(zend_accel_hash *accel_hash, char *key, uint32_t key_length, zend_ulong hash_value, int data) { - zend_ulong index = hash_value % accel_hash->max_num_entries; - zend_accel_hash_entry *entry = accel_hash->hash_table[index]; + zend_ulong index; + zend_accel_hash_entry *entry; +#ifndef ZEND_WIN32 + hash_value ^= ZCG(root_hash); +#endif + index = hash_value % accel_hash->max_num_entries; + + entry = accel_hash->hash_table[index]; while (entry) { if (entry->hash_value == hash_value && entry->key_length == key_length @@ -224,6 +233,9 @@ int zend_accel_hash_unlink(zend_accel_hash *accel_hash, char *key, uint32_t key_ zend_accel_hash_entry *entry, *last_entry=NULL; hash_value = zend_inline_hash_func(key, key_length); +#ifndef ZEND_WIN32 + hash_value ^= ZCG(root_hash); +#endif index = hash_value % accel_hash->max_num_entries; entry = accel_hash->hash_table[index]; diff --git a/ext/opcache/zend_accelerator_module.c b/ext/opcache/zend_accelerator_module.c index b8a3410895..7feaaf6584 100644 --- a/ext/opcache/zend_accelerator_module.c +++ b/ext/opcache/zend_accelerator_module.c @@ -272,6 +272,8 @@ ZEND_INI_BEGIN() STD_PHP_INI_BOOLEAN("opcache.enable" , "1", PHP_INI_ALL, OnEnable, enabled , zend_accel_globals, accel_globals) STD_PHP_INI_BOOLEAN("opcache.use_cwd" , "1", PHP_INI_SYSTEM, OnUpdateBool, accel_directives.use_cwd , zend_accel_globals, accel_globals) STD_PHP_INI_BOOLEAN("opcache.validate_timestamps", "1", PHP_INI_ALL , OnUpdateBool, accel_directives.validate_timestamps, zend_accel_globals, accel_globals) + STD_PHP_INI_BOOLEAN("opcache.validate_permission", "0", PHP_INI_SYSTEM, OnUpdateBool, accel_directives.validate_permission, zend_accel_globals, accel_globals) + STD_PHP_INI_BOOLEAN("opcache.validate_root" , "0", PHP_INI_SYSTEM, OnUpdateBool, accel_directives.validate_root , zend_accel_globals, accel_globals) STD_PHP_INI_BOOLEAN("opcache.inherited_hack" , "1", PHP_INI_SYSTEM, OnUpdateBool, accel_directives.inherited_hack , zend_accel_globals, accel_globals) STD_PHP_INI_BOOLEAN("opcache.dups_fix" , "0", PHP_INI_ALL , OnUpdateBool, accel_directives.ignore_dups , zend_accel_globals, accel_globals) STD_PHP_INI_BOOLEAN("opcache.revalidate_path" , "0", PHP_INI_ALL , OnUpdateBool, accel_directives.revalidate_path , zend_accel_globals, accel_globals) @@ -691,6 +693,8 @@ static ZEND_FUNCTION(opcache_get_configuration) add_assoc_bool(&directives, "opcache.enable_cli", ZCG(accel_directives).enable_cli); add_assoc_bool(&directives, "opcache.use_cwd", ZCG(accel_directives).use_cwd); add_assoc_bool(&directives, "opcache.validate_timestamps", ZCG(accel_directives).validate_timestamps); + add_assoc_bool(&directives, "opcache.validate_permission", ZCG(accel_directives).validate_permission); + add_assoc_bool(&directives, "opcache.validate_root", ZCG(accel_directives).validate_root); add_assoc_bool(&directives, "opcache.inherited_hack", ZCG(accel_directives).inherited_hack); add_assoc_bool(&directives, "opcache.dups_fix", ZCG(accel_directives).ignore_dups); add_assoc_bool(&directives, "opcache.revalidate_path", ZCG(accel_directives).revalidate_path); |