From: Anatol Belski Date: Wed, 31 Jan 2018 19:15:30 +0000 (+0100) Subject: Fix race conditions with Apache vhost vs. per dir config X-Git-Tag: php-7.1.15RC1~15 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bced074124f65653071ccf29e0878ef725b09a49;p=php Fix race conditions with Apache vhost vs. per dir config 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. (cherry picked from commit 73eb5a78b9caa18d35624765f9b972c1ba48855d) --- diff --git a/sapi/apache2handler/apache_config.c b/sapi/apache2handler/apache_config.c index bd017535b8..05c9e85828 100644 --- a/sapi/apache2handler/apache_config.c +++ b/sapi/apache2handler/apache_config.c @@ -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);