]> granicus.if.org Git - php/commitdiff
Fix race conditions with Apache vhost vs. per dir config
authorAnatol Belski <ab@php.net>
Wed, 31 Jan 2018 19:15:30 +0000 (20:15 +0100)
committerAnatol Belski <ab@php.net>
Wed, 31 Jan 2018 19:15:30 +0000 (20:15 +0100)
If the same php_value/php_flag is present in httpd.conf and .htaccess,
the key is potentially shared between threads. Unfortunately we can't
intern these keys using the current mechanism, because the MPM is setup
before the SAPI module setup is even started. A more elegant way were
to implement a kind of string pool for the thread safe Apache SAPI
config directives with the mechanism similar to what is done for the
SAPI setup now, but doing a separate management.

sapi/apache2handler/apache_config.c

index bd017535b8567bb9345387a0a976f354900ec948..05c9e858289e197d054d966088cbae14b4451810 100644 (file)
@@ -147,10 +147,28 @@ void config_entry_ctor(zval *zv)
 void *merge_php_config(apr_pool_t *p, void *base_conf, void *new_conf)
 {
        php_conf_rec *d = base_conf, *e = new_conf, *n = NULL;
+#ifdef ZTS
+       zend_string *str;
+       zval *data;
+#endif
 
        n = create_php_config(p, "merge_php_config");
        /* copy old config */
+#ifdef ZTS
+       ZEND_HASH_FOREACH_STR_KEY_VAL(&d->config, str, data) {
+               zend_string *key;
+               zval *new_entry;
+
+               /* Avoid sharing the non interned string among threads. */
+               key = zend_string_dup(str, 1);
+
+               new_entry = zend_hash_add(&n->config, key, data);
+
+               config_entry_ctor(new_entry);
+       } ZEND_HASH_FOREACH_END();
+#else
        zend_hash_copy(&n->config, &d->config, config_entry_ctor);
+#endif
        /* merge new config */
        phpapdebug((stderr, "Merge dir (%p)+(%p)=(%p)\n", base_conf, new_conf, n));
        zend_hash_merge_ex(&n->config, &e->config, config_entry_ctor, should_overwrite_per_dir_entry, NULL);