php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #25753 php_value|flag / php_admin_* settings "leak" from vhosts/.htaccess files
Submitted: 2003-10-04 00:48 UTC Modified: 2004-02-13 12:54 UTC
Votes:104
Avg. Score:4.8 ± 0.6
Reproduced:97 of 99 (98.0%)
Same Version:50 (51.5%)
Same OS:70 (72.2%)
From: sniper@php.net Assigned:
Status: Closed Package: Apache related
PHP Version: 4CVS, 5CVS OS: *
Private report: No CVE-ID: None
 [2003-10-04 00:48 UTC] sniper@php.net
Description:
------------
If (for example) one virtualhost configuration has
set "php_admin_flag register_globals off", in some situations the setting persists between requests.
-> php.ini settings are NOT reset between requests.

1. php.ini has register_globals = On
2. Request is made into www.foobar.com 
(which has "php_admin_flag register_globals off")
3. Next request (same apache child) is made into www.barfoo.com (which does not have the setting)

This applies to ALL php.ini directives.

Some related reports:

bug #6374 (include_path in .htaccess across multiple vhosts)
bug #7174 (Round-robin -like values for include_path)
bug #19292 (Random error: open_basedir restriction..)
bug #21564 (corrupted paths coming to open_basedir)
bug #23462 ("php_admin_value open_basedir" in httpd.conf)
bug #23580 (Random values for include_path)
bug #24282 (Strange Open Base Dir Restriction Errors)
bug #24974 (random open_basedir errors)
bug #25172 ($HTTP_HOST sometimes empty)

For all who think they're experiencing this problem:
DO NOT add any comments here unless you have some extra information to give which is not already given in above mentioned reports. 
Any comment which has no extra value will be deleted.



Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2003-10-04 18:58 UTC] sniper@php.net
We do not know what causes this bug or how it can be reliably reproduced. If you know exactly HOW this can be reproduced, add the information here. Any other comments will be deleted.

 [2004-01-27 13:36 UTC] rover at tob dot ru
It seems we have found a bug in mod_php4.c. We can 100% reproduce this error. How to reproduce (our case):
in httpd.conf we have:

# to enable only one instance of apache process
StartServers 1
MaxClients 1
#
<Directory /var/www/info/>
    php_value engine off
</Directory>

in php.ini:
Engine = On,
we enable php-scripts at all site, but disable in /info.

Let's begin:
#/usr/sbin/apache.dbg -f /etc/apache/httpd.conf
#gbd /usr/sbin/apache.gdb pid_of_child (attach to child, what serve requests)
(gdb)p php_apache_info.engine
 =1                                    ! php-engine ENABLED
(gdb)watch php_apache_info.engine      ! VERY IMPORTANT
(gdb)break send_php                    ! bug in this func.
(gdb)c

1) Request a usual file from http://our.site/info/index.html:
Because we define 'php_value off' for this directory - at line 829 in function php_xbithack_handler(remember - we process text/html) we call
zend_hash_apply((HashTable *) per_dir_conf, (apply_func_t) php_apache_alter_ini_entries TSRMLS_CC);
and change our 'engine' value to 0.
backtrace for this call (don't look at line number - they shifted because i insert debug lines in source files):
Hardware watchpoint 1: php_apache_info.engine
Old value = 1
New value = 0
#0  OnUpdateInt (entry=0x80dc778, new_value=0x80d3cc4 "off", new_value_length=3, mh_arg1=0x0, mh_arg2=0x4057f92c,
    mh_arg3=0x0, stage=4) at /usr/local/src/apache2+php4/php4-4.3.3/Zend/zend_ini.c:453
#1  0x4051110a in zend_alter_ini_entry (name=0x80de170 "engine", name_length=7, new_value=0x80de180 "off",
    new_value_length=3, modify_type=2, stage=4) at /usr/local/src/apache2+php4/php4-4.3.3/Zend/zend_ini.c:212
#2  0x40519fc6 in php_apache_alter_ini_entries (per_dir_entry=0x812c598)
    at /usr/local/src/apache2+php4/php4-4.3.3/sapi/apache/mod_php4.c:511
#3  0x4050b8f9 in zend_hash_apply (ht=0x809fc98, apply_func=0x40519f40 <php_apache_alter_ini_entries>)
    at /usr/local/src/apache2+php4/php4-4.3.3/Zend/zend_hash.c:698
#4  0x4051ad1b in php_xbithack_handler (r=0x81367ec)
    at /usr/local/src/apache2+php4/php4-4.3.3/sapi/apache/mod_php4.c:850
#5  0x080551c3 in ap_invoke_handler (r=0x81367ec) at http_config.c:518
#6  0x08067e28 in process_request_internal (r=0x81367ec) at http_request.c:1332
#7  0x08067fd4 in ap_process_request (r=0x81367ec) at http_request.c:1348
#8  0x08060644 in child_main (child_num_arg=0) at http_main.c:4719
#9  0x080607f7 in make_child (s=0x0, slot=0, now=0) at http_main.c:4898
#10 0x08060920 in startup_children (number_to_start=1) at http_main.c:4925
#11 0x0806149a in standalone_main (argc=1, argv=0xbffffdf4) at http_main.c:5244
#12 0x08061a08 in main (argc=1, argv=0xbffffdf4) at http_main.c:5601

Result of 1): we process http://our.site/info/index.html succefull and set global var 'engine'=0!

Now we try to access http://our.site/index.php
2) breakpoint 2 executed:
Breakpoint 2, send_php (r=0x81367ec, display_source_mode=0, filename=0x0)
    at /usr/local/src/apache2+php4/php4-4.3.3/sapi/apache/mod_php4.c:544
544                     fh.free_filename = 0;
#0  send_php (r=0x81367ec, display_source_mode=0, filename=0x0)
    at /usr/local/src/apache2+php4/php4-4.3.3/sapi/apache/mod_php4.c:544
#1  0x4051a6eb in send_parsed_php (r=0x81367ec) at /usr/local/src/apache2+php4/php4-4.3.3/sapi/apache/mod_php4.c:655
#2  0x080551c3 in ap_invoke_handler (r=0x81367ec) at http_config.c:518
#3  0x08067e28 in process_request_internal (r=0x81367ec) at http_request.c:1332
#4  0x08067fd4 in ap_process_request (r=0x81367ec) at http_request.c:1348
#5  0x08060644 in child_main (child_num_arg=135489516) at http_main.c:4719
#6  0x080607f7 in make_child (s=0x81367ec, slot=0, now=135489516) at http_main.c:4898
#7  0x08060920 in startup_children (number_to_start=1) at http_main.c:4925
#8  0x0806149a in standalone_main (argc=1, argv=0xbffffdf4) at http_main.c:5244
#9  0x08061a08 in main (argc=1, argv=0xbffffdf4) at http_main.c:5601

But look at 'engine' - IT HAVE OLD VALUE = 0! What happend next:

In mod_php4.c at line 570(original file from 4.3.3,4.3.4,4.3.5RC1) we have:
        if (!AP(engine)) {
                r->content_type = php_apache_get_default_mimetype(r TSRMLS_CC);
                r->allowed |= (1 << METHODS) - 1;
                zend_try {
                        zend_ini_deactivate(TSRMLS_C);
                } zend_end_try();
                return DECLINED;
        }

and instead serve index.php as x-application-php we only return DECLINE. Continue:

3)(gdb)c
Hardware watchpoint 1: php_apache_info.engine
Old value = 0
New value = 1
OnUpdateInt (entry=0x80dc778, new_value=0x80b53e0 "1", new_value_length=1, mh_arg1=0x0, mh_arg2=0x4057f92c,
    mh_arg3=0x0, stage=8) at /usr/local/src/apache2+php4/php4-4.3.3/Zend/zend_ini.c:453
453
1: php_apache_info = {engine = 1, last_modified = 0, xbithack = 0, terminate_child = 0, in_request = 0 '\0'}
(gdb) bt
#0  OnUpdateInt (entry=0x80dc778, new_value=0x80b53e0 "1", new_value_length=1, mh_arg1=0x0, mh_arg2=0x4057f92c,
    mh_arg3=0x0, stage=8) at /usr/local/src/apache2+php4/php4-4.3.3/Zend/zend_ini.c:453
#1  0x40510bcf in zend_restore_ini_entry_cb (ini_entry=0x80dc778, stage=8)
    at /usr/local/src/apache2+php4/php4-4.3.3/Zend/zend_ini.c:51
#2  0x4050b990 in zend_hash_apply_with_argument (ht=0x80b4f48, apply_func=0x40510b40 <zend_restore_ini_entry_cb>,
    argument=0x8) at /usr/local/src/apache2+php4/php4-4.3.3/Zend/zend_hash.c:717
#3  0x40510cdb in zend_ini_deactivate () at /usr/local/src/apache2+php4/php4-4.3.3/Zend/zend_ini.c:89
#4  0x40510b40 in zend_remove_ini_entries (ini_entry=0x90, module_number=0x0)
    at /usr/local/src/apache2+php4/php4-4.3.3/Zend/zend_ini.c:44

This only happend at line 574 where we RESET all variables to default value.

To solve this bug we must RESET all ini_entries to default values in send_php function. Maybe authors suggest better method to restore default values instead using zend_ini_deactivate(TSRMLS_C);
 [2004-01-28 00:47 UTC] rover at tob dot ru
We examine source files more carefull and remake a patch:

diff -udr php-4.3.3/sapi/apache/mod_php4.c php-4.3.3.patched/sapi/apache/mod_php4.c
--- php-4.3.3/sapi/apache/mod_php4.c    2003-06-03 11:41:49.000000000 +0600
+++ php-4.3.3.patched/sapi/apache/mod_php4.c    2004-01-28 10:48:27.000000000 +0500
@@ -830,6 +830,9 @@
        }
        if(!AP(xbithack)) {
                r->allowed |= (1 << METHODS) - 1;
+               zend_try {
+                       zend_ini_deactivate(TSRMLS_C);
+               } zend_end_try();
                return DECLINED;
        }
        return send_parsed_php(r);
 [2004-01-28 12:40 UTC] rasmus@php.net
This only happens on text/html files with the executable bit set.  If the +x bit is set, we load the current ini settings and if php's xbithack option is not set we decline the request but forget to reset the ini settings potentially leaking them to the next request.  This is now fixed in CVS and will be in the next release of both PHP4 and PHP5.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Mar 19 05:01:29 2024 UTC