Skip to content

Commit 841e7a1

Browse files
dstogovsgolemon
authored andcommitted
Fixed bug #75579 (Interned strings buffer overflow may cause crash)
1 parent f8cdcf2 commit 841e7a1

File tree

2 files changed

+34
-2
lines changed

2 files changed

+34
-2
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ PHP NEWS
33
?? ??? ????, PHP 7.2.1
44

55

6+
- Opcache:
7+
. Fixed bug #75579 (Interned strings buffer overflow may cause crash).
8+
(Dmitry)
9+
610
14 Dec 2017, PHP 7.2.1RC1
711

812
- Core:

ext/opcache/zend_file_cache.c

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,8 +227,17 @@ static void *zend_file_cache_unserialize_interned(zend_string *str, int in_shm)
227227
if (in_shm) {
228228
ret = accel_new_interned_string(str);
229229
if (ret == str) {
230+
/* We have to create new SHM allocated string */
231+
size_t size = _ZSTR_STRUCT_SIZE(ZSTR_LEN(str));
232+
ret = zend_shared_alloc(size);
233+
if (!ret) {
234+
zend_accel_schedule_restart_if_necessary(ACCEL_RESTART_OOM);
235+
LONGJMP(*EG(bailout), FAILURE);
236+
}
237+
memcpy(ret, str, size);
230238
/* String wasn't interned but we will use it as interned anyway */
231-
GC_FLAGS(ret) |= IS_STR_INTERNED | IS_STR_PERMANENT;
239+
GC_REFCOUNT(ret) = 1;
240+
GC_TYPE_INFO(ret) = IS_STRING | ((IS_STR_INTERNED | IS_STR_PERSISTENT | IS_STR_PERMANENT) << 8);
232241
}
233242
} else {
234243
ret = str;
@@ -1303,6 +1312,7 @@ zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handl
13031312
zend_accel_hash_entry *bucket;
13041313
void *mem, *checkpoint, *buf;
13051314
int cache_it = 1;
1315+
int ok;
13061316

13071317
if (!full_path) {
13081318
return NULL;
@@ -1395,6 +1405,7 @@ zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handl
13951405

13961406
if (!ZCG(accel_directives).file_cache_only &&
13971407
!ZCSG(restart_in_progress) &&
1408+
!ZSMMG(memory_exhausted) &&
13981409
accelerator_shm_read_lock() == SUCCESS) {
13991410
/* exclusive lock */
14001411
zend_shared_alloc_lock();
@@ -1444,7 +1455,24 @@ zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handl
14441455
ZCG(mem) = ((char*)mem + info.mem_size);
14451456
script = (zend_persistent_script*)((char*)buf + info.script_offset);
14461457
script->corrupted = !cache_it; /* used to check if script restored to SHM or process memory */
1447-
zend_file_cache_unserialize(script, buf);
1458+
1459+
ok = 1;
1460+
zend_try {
1461+
zend_file_cache_unserialize(script, buf);
1462+
} zend_catch {
1463+
ok = 0;
1464+
} zend_end_try();
1465+
if (!ok) {
1466+
if (cache_it) {
1467+
zend_shared_alloc_unlock();
1468+
goto use_process_mem;
1469+
} else {
1470+
zend_arena_release(&CG(arena), checkpoint);
1471+
efree(filename);
1472+
return NULL;
1473+
}
1474+
}
1475+
14481476
script->corrupted = 0;
14491477

14501478
if (cache_it) {

0 commit comments

Comments
 (0)