]> granicus.if.org Git - php/commitdiff
Replaced usafe reference from SHM to process memory with SHM to SHM reference.
authorDmitry Stogov <dmitry@zend.com>
Mon, 5 Mar 2018 23:43:26 +0000 (02:43 +0300)
committerDmitry Stogov <dmitry@zend.com>
Mon, 5 Mar 2018 23:43:26 +0000 (02:43 +0300)
ext/opcache/ZendAccelerator.c
ext/opcache/ZendAccelerator.h
ext/opcache/zend_persist.c
ext/opcache/zend_persist.h

index 11b2c4ea778272f6e0edc205fd6b99c3a2b9e919..d983d4c0567269adf056190f2fbaf9e70c947bf1 100644 (file)
@@ -1235,8 +1235,8 @@ static zend_persistent_script *store_script_in_file_cache(zend_persistent_script
        ZCG(mem) = zend_arena_alloc(&CG(arena), memory_used);
 #endif
 
-       /* Copy into shared memory */
-       new_persistent_script = zend_accel_script_persist(new_persistent_script, NULL, 0);
+       /* Copy into memory block */
+       new_persistent_script = zend_accel_script_persist(new_persistent_script, NULL, 0, 0);
 
        zend_shared_alloc_destroy_xlat_table();
 
@@ -1355,7 +1355,7 @@ static zend_persistent_script *cache_script_in_shared_memory(zend_persistent_scr
        }
 
        /* Copy into shared memory */
-       new_persistent_script = zend_accel_script_persist(new_persistent_script, &key, key_length);
+       new_persistent_script = zend_accel_script_persist(new_persistent_script, &key, key_length, 1);
 
        zend_shared_alloc_destroy_xlat_table();
 
@@ -2526,6 +2526,8 @@ static inline int accel_find_sapi(void)
 
 static int zend_accel_init_shm(void)
 {
+       int i;
+
        zend_shared_alloc_lock();
 
        accel_shared_globals = zend_shared_alloc(sizeof(zend_accel_shared_globals));
@@ -2589,6 +2591,11 @@ static int zend_accel_init_shm(void)
        ZCSG(last_restart_time) = 0;
        ZCSG(restart_in_progress) = 0;
 
+
+       for (i = 0; i < -HT_MIN_MASK; i++) {
+               ZCSG(uninitialized_bucket)[i] = HT_INVALID_IDX;
+       }
+
        zend_shared_alloc_unlock();
 
        return SUCCESS;
index d0f69d6b7c9b5bf17042b6cb7db96df105f246b2..a1db3ee7a57d927eb0e8bd0a3f64e645e7fc465a 100644 (file)
@@ -283,6 +283,8 @@ typedef struct _zend_accel_shared_globals {
        char           *interned_strings_end;
        char           *interned_strings_saved_top;
        HashTable       interned_strings;
+       /* uninitialized HashTable Support */
+       uint32_t uninitialized_bucket[-HT_MIN_MASK];
 } zend_accel_shared_globals;
 
 extern zend_bool accel_startup_ok;
index 3e55331313c9a0fed52f376d5f5eb317e33abc58..830b3883c8f30dc91165a335d91d6a9d928ae6d1 100644 (file)
@@ -89,13 +89,21 @@ static void zend_hash_persist(HashTable *ht, zend_persist_func_t pPersistElement
        ht->pDestructor = NULL;
 
        if (!(ht->u.flags & HASH_FLAG_INITIALIZED)) {
-               HT_SET_DATA_ADDR(ht, &uninitialized_bucket);
+               if (EXPECTED(!ZCG(current_persistent_script)->corrupted)) {
+                       HT_SET_DATA_ADDR(ht, &ZCSG(uninitialized_bucket));
+               } else {
+                       HT_SET_DATA_ADDR(ht, &uninitialized_bucket);
+               }
                return;
        }
        if (ht->nNumUsed == 0) {
                efree(HT_GET_DATA_ADDR(ht));
                ht->nTableMask = HT_MIN_MASK;
-               HT_SET_DATA_ADDR(ht, &uninitialized_bucket);
+               if (EXPECTED(!ZCG(current_persistent_script)->corrupted)) {
+                       HT_SET_DATA_ADDR(ht, &ZCSG(uninitialized_bucket));
+               } else {
+                       HT_SET_DATA_ADDR(ht, &uninitialized_bucket);
+               }
                ht->u.flags &= ~HASH_FLAG_INITIALIZED;
                return;
        }
@@ -175,13 +183,21 @@ static void zend_hash_persist_immutable(HashTable *ht)
        ht->pDestructor = NULL;
 
        if (!(ht->u.flags & HASH_FLAG_INITIALIZED)) {
-               HT_SET_DATA_ADDR(ht, &uninitialized_bucket);
+               if (EXPECTED(!ZCG(current_persistent_script)->corrupted)) {
+                       HT_SET_DATA_ADDR(ht, &ZCSG(uninitialized_bucket));
+               } else {
+                       HT_SET_DATA_ADDR(ht, &uninitialized_bucket);
+               }
                return;
        }
        if (ht->nNumUsed == 0) {
                efree(HT_GET_DATA_ADDR(ht));
                ht->nTableMask = HT_MIN_MASK;
-               HT_SET_DATA_ADDR(ht, &uninitialized_bucket);
+               if (EXPECTED(!ZCG(current_persistent_script)->corrupted)) {
+                       HT_SET_DATA_ADDR(ht, &ZCSG(uninitialized_bucket));
+               } else {
+                       HT_SET_DATA_ADDR(ht, &uninitialized_bucket);
+               }
                ht->u.flags &= ~HASH_FLAG_INITIALIZED;
                return;
        }
@@ -833,9 +849,16 @@ static void zend_accel_persist_class_table(HashTable *class_table)
        zend_hash_apply(class_table, (apply_func_t) zend_update_parent_ce);
 }
 
-zend_persistent_script *zend_accel_script_persist(zend_persistent_script *script, char **key, unsigned int key_length)
+zend_persistent_script *zend_accel_script_persist(zend_persistent_script *script, char **key, unsigned int key_length, int for_shm)
 {
        script->mem = ZCG(mem);
+       script->corrupted = 0;
+       ZCG(current_persistent_script) = script;
+
+       if (!for_shm) {
+               /* script is not going to be saved in SHM */
+               script->corrupted = 1;
+       }
 
        ZEND_ASSERT(((zend_uintptr_t)ZCG(mem) & 0x7) == 0); /* should be 8 byte aligned */
        zend_shared_alloc_clear_xlat_table();
@@ -860,6 +883,9 @@ zend_persistent_script *zend_accel_script_persist(zend_persistent_script *script
        zend_hash_persist(&script->script.function_table, zend_persist_op_array);
        zend_persist_op_array_ex(&script->script.main_op_array, script);
 
+       script->corrupted = 0;
+       ZCG(current_persistent_script) = NULL;
+
        return script;
 }
 
index 67561882a6cfcaac7df331c864703803d29f068e..166c08fd139611a36527de4f2b0c3f1e1ad21e29 100644 (file)
@@ -24,6 +24,6 @@
 
 int zend_accel_script_persistable(zend_persistent_script *script);
 uint zend_accel_script_persist_calc(zend_persistent_script *script, char *key, unsigned int key_length, int for_shm);
-zend_persistent_script *zend_accel_script_persist(zend_persistent_script *script, char **key, unsigned int key_length);
+zend_persistent_script *zend_accel_script_persist(zend_persistent_script *script, char **key, unsigned int key_length, int for_shm);
 
 #endif /* ZEND_PERSIST_H */