Skip to content

Commit a1a5b52

Browse files
committed
Merge branch 'PHP-5.6' into PHP-7.0
* PHP-5.6: Fixed bug #69090 (check cached files permissions)
2 parents 22a4355 + ecba563 commit a1a5b52

File tree

6 files changed

+77
-4
lines changed

6 files changed

+77
-4
lines changed

NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ PHP NEWS
1616
. Fixed bug #73448 (odbc_errormsg returns trash, always 513 bytes).
1717
(Anatol)
1818

19+
- Opcache:
20+
. Fixed bug #69090 (check cached files permissions)
21+
1922
- PCRE:
2023
. Fixed bug #73392 (A use-after-free in zend allocator management).
2124
(Laruence)

ext/opcache/README

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,16 @@ opcache.validate_timestamps (default "1")
102102
The frequency of the check is controlled by the directive
103103
"opcache.revalidate_freq".
104104

105+
opcache.validate_permission (default "0")
106+
Leads OPcache to check file readability on each access to cached file.
107+
This directive should be enabled in shared hosting environment, when few
108+
users (PHP-FPM pools) reuse the common OPcache shared memory.
109+
110+
opcache.validate_root (default "0")
111+
This directive prevents file name collisions in different "chroot"
112+
environments. It should be enabled for sites that may serve requests in
113+
different "chroot" environments.
114+
105115
opcache.revalidate_freq (default "2")
106116
How often (in seconds) to check file timestamps for changes to the shared
107117
memory storage allocation. ("1" means validate once per second, but only

ext/opcache/ZendAccelerator.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1763,6 +1763,20 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type)
17631763
ZCG(counted) = 1;
17641764
}
17651765

1766+
/* Revalidate acessibility of cached file */
1767+
if (EXPECTED(persistent_script != NULL) &&
1768+
UNEXPECTED(ZCG(accel_directives).validate_permission) &&
1769+
file_handle->type == ZEND_HANDLE_FILENAME &&
1770+
UNEXPECTED(access(file_handle->filename, R_OK) != 0)) {
1771+
if (type == ZEND_REQUIRE) {
1772+
zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, file_handle->filename TSRMLS_CC);
1773+
zend_bailout();
1774+
} else {
1775+
zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, file_handle->filename TSRMLS_CC);
1776+
}
1777+
return NULL;
1778+
}
1779+
17661780
SHM_UNPROTECT();
17671781

17681782
/* If script is found then validate_timestamps if option is enabled */
@@ -2070,6 +2084,31 @@ static void accel_activate(void)
20702084
}
20712085
#endif
20722086

2087+
#ifndef ZEND_WIN32
2088+
if (ZCG(accel_directives).validate_root) {
2089+
struct stat buf;
2090+
2091+
if (stat("/", &buf) != 0) {
2092+
ZCG(root_hash) = 0;
2093+
} else {
2094+
zend_ulong x = buf.st_ino;
2095+
2096+
#if SIZEOF_ZEND_LONG == 4
2097+
x = ((x >> 16) ^ x) * 0x45d9f3b;
2098+
x = ((x >> 16) ^ x) * 0x45d9f3b;
2099+
x = (x >> 16) ^ x;
2100+
#elif SIZEOF_ZEND_LONG == 8
2101+
x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
2102+
x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
2103+
x = x ^ (x >> 31);
2104+
#endif
2105+
ZCG(root_hash) = x;
2106+
}
2107+
} else {
2108+
ZCG(root_hash) = 0;
2109+
}
2110+
#endif
2111+
20732112
SHM_UNPROTECT();
20742113

20752114
if (ZCG(counted)) {

ext/opcache/ZendAccelerator.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,8 +202,10 @@ typedef struct _zend_accel_directives {
202202
zend_bool file_override_enabled;
203203
zend_bool inherited_hack;
204204
zend_bool enable_cli;
205-
zend_ulong revalidate_freq;
206-
zend_ulong file_update_protection;
205+
zend_bool validate_permission;
206+
zend_bool validate_root;
207+
zend_ulong revalidate_freq;
208+
zend_ulong file_update_protection;
207209
char *error_log;
208210
#ifdef ZEND_WIN32
209211
char *mmap_base;
@@ -254,6 +256,9 @@ typedef struct _zend_accel_globals {
254256
time_t last_restart_time; /* used to synchronize SHM and in-process caches */
255257
char system_id[32];
256258
HashTable xlat_table;
259+
#ifndef ZEND_WIN32
260+
zend_ulong root_hash;
261+
#endif
257262
/* preallocated shared-memory block to save current script */
258263
void *mem;
259264
void *arena_mem;

ext/opcache/zend_accelerator_hash.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ zend_accel_hash_entry* zend_accel_hash_update(zend_accel_hash *accel_hash, char
8686
}
8787

8888
hash_value = zend_inline_hash_func(key, key_length);
89+
#ifndef ZEND_WIN32
90+
hash_value ^= ZCG(root_hash);
91+
#endif
8992
index = hash_value % accel_hash->max_num_entries;
9093

9194
/* 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
139142

140143
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)
141144
{
142-
zend_ulong index = hash_value % accel_hash->max_num_entries;
143-
zend_accel_hash_entry *entry = accel_hash->hash_table[index];
145+
zend_ulong index;
146+
zend_accel_hash_entry *entry;
144147

148+
#ifndef ZEND_WIN32
149+
hash_value ^= ZCG(root_hash);
150+
#endif
151+
index = hash_value % accel_hash->max_num_entries;
152+
153+
entry = accel_hash->hash_table[index];
145154
while (entry) {
146155
if (entry->hash_value == hash_value
147156
&& entry->key_length == key_length
@@ -224,6 +233,9 @@ int zend_accel_hash_unlink(zend_accel_hash *accel_hash, char *key, uint32_t key_
224233
zend_accel_hash_entry *entry, *last_entry=NULL;
225234

226235
hash_value = zend_inline_hash_func(key, key_length);
236+
#ifndef ZEND_WIN32
237+
hash_value ^= ZCG(root_hash);
238+
#endif
227239
index = hash_value % accel_hash->max_num_entries;
228240

229241
entry = accel_hash->hash_table[index];

ext/opcache/zend_accelerator_module.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,8 @@ ZEND_INI_BEGIN()
272272
STD_PHP_INI_BOOLEAN("opcache.enable" , "1", PHP_INI_ALL, OnEnable, enabled , zend_accel_globals, accel_globals)
273273
STD_PHP_INI_BOOLEAN("opcache.use_cwd" , "1", PHP_INI_SYSTEM, OnUpdateBool, accel_directives.use_cwd , zend_accel_globals, accel_globals)
274274
STD_PHP_INI_BOOLEAN("opcache.validate_timestamps", "1", PHP_INI_ALL , OnUpdateBool, accel_directives.validate_timestamps, zend_accel_globals, accel_globals)
275+
STD_PHP_INI_BOOLEAN("opcache.validate_permission", "0", PHP_INI_SYSTEM, OnUpdateBool, accel_directives.validate_permission, zend_accel_globals, accel_globals)
276+
STD_PHP_INI_BOOLEAN("opcache.validate_root" , "0", PHP_INI_SYSTEM, OnUpdateBool, accel_directives.validate_root , zend_accel_globals, accel_globals)
275277
STD_PHP_INI_BOOLEAN("opcache.inherited_hack" , "1", PHP_INI_SYSTEM, OnUpdateBool, accel_directives.inherited_hack , zend_accel_globals, accel_globals)
276278
STD_PHP_INI_BOOLEAN("opcache.dups_fix" , "0", PHP_INI_ALL , OnUpdateBool, accel_directives.ignore_dups , zend_accel_globals, accel_globals)
277279
STD_PHP_INI_BOOLEAN("opcache.revalidate_path" , "0", PHP_INI_ALL , OnUpdateBool, accel_directives.revalidate_path , zend_accel_globals, accel_globals)
@@ -690,6 +692,8 @@ static ZEND_FUNCTION(opcache_get_configuration)
690692
add_assoc_bool(&directives, "opcache.enable_cli", ZCG(accel_directives).enable_cli);
691693
add_assoc_bool(&directives, "opcache.use_cwd", ZCG(accel_directives).use_cwd);
692694
add_assoc_bool(&directives, "opcache.validate_timestamps", ZCG(accel_directives).validate_timestamps);
695+
add_assoc_bool(&directives, "opcache.validate_permission", ZCG(accel_directives).validate_permission);
696+
add_assoc_bool(&directives, "opcache.validate_root", ZCG(accel_directives).validate_root);
693697
add_assoc_bool(&directives, "opcache.inherited_hack", ZCG(accel_directives).inherited_hack);
694698
add_assoc_bool(&directives, "opcache.dups_fix", ZCG(accel_directives).ignore_dups);
695699
add_assoc_bool(&directives, "opcache.revalidate_path", ZCG(accel_directives).revalidate_path);

0 commit comments

Comments
 (0)