php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #41561 Values set with php_admin_* in httpd.conf can be overwritten with ini_set()
Submitted: 2007-06-01 15:23 UTC Modified: 2007-09-07 09:39 UTC
Votes:9
Avg. Score:4.4 ± 1.3
Reproduced:4 of 6 (66.7%)
Same Version:0 (0.0%)
Same OS:2 (50.0%)
From: samy-delux at gmx dot de Assigned: tony2001
Status: Closed Package: PHP options/info functions
PHP Version: 5.2.3 OS: Ubuntu Linux
Private report: No CVE-ID:
 [2007-06-01 15:23 UTC] samy-delux at gmx dot de
Description:
------------
When I set a value inside the httpd.conf with php_admin_value or php_admin_flag that is INI_ALL or INI_PERDIR it can be overwritten at runtime using ini_set()

I don't think this should be possible. But the documentation on this problem doesn't assure me if this is a bug or a feature!

Reproduce code:
---------------
/etc/apache2/httpd.conf :
php_admin_value memory_limit 3145728


iniset_test.php :
<?php

$old = ini_set("memory_limit", 20971520);

echo "old: ".$old;

$new = ini_get("memory_limit");

echo "<br>new: ".$new;

?>

Expected result:
----------------
The result is the following:
old: 3145728
new: 3145728 

Actual result:
--------------
The result is the following:
old: 3145728
new: 20971520 

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2007-06-01 15:41 UTC] sniper@php.net
I don't have apache setup, so can you try and see if that actually changes it for real? ie. something like:

$s = '';
while(1) $s.='fooooooooooooooooooooooooooooooooooooo';


 [2007-06-01 15:49 UTC] samy-delux at gmx dot de
It does change it for real:

$foo = str_repeat('bla', 19922944);
 [2007-06-01 16:29 UTC] sniper@php.net
And the error you get..?
 [2007-06-01 16:40 UTC] samy-delux at gmx dot de
There is no error! The limit is set to 3MB with php_admin_value. Then I change it with ini_set() to 20MB and I can allocate 19MB (well, almost 20MB)...
When I don NOT ini_set() and leave the limit at 3MB it raises the following error:

Fatal error: Allowed memory size of 3145728 bytes exhausted (tried to allocate 19971501 bytes) in /var/www/iniset.php on line 11
 [2007-06-02 22:48 UTC] sniper@php.net
Can you try with some other ini option too, so we know this is general issue with php_admin_* directives and not just this one.

include_path is good choice. 
 [2007-06-03 14:18 UTC] samy-delux at gmx dot de
I tried it with include_path and it does work as well:

'inc.php' lies in '/var/www/test/prohibited_include' and should not be includeable!

Reproduce code:
---------------
/etc/apache2/httpd.conf :
php_admin_value include_path "/var/www/test/allowed_include"

path.php :
<?php
ini_set("include_path", "/var/www/test/prohibited_include");
include("inc.php");
?>

Expected result:
----------------
The result is the following:
Warning: include(inc.php) [function.include]: failed to open stream: No such file or directory in /var/www/test/path.php on line 5

Warning: include() [function.include]: Failed opening 'inc.php' for inclusion (include_path='/var/www/test/allowed_include') in /var/www/test/path.php on line 5

Actual result:
--------------
The result is the following:
No Error because the file gets included nicely!
 [2007-06-05 15:02 UTC] genetiq at gmail dot com
can reproduce this bug on my machine (Mac OS X 10.4.9, Apache2, PHP 
5.2.3)
 [2007-06-08 14:48 UTC] tony2001@php.net
This bug has been fixed in CVS.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.
 
Thank you for the report, and for helping us make PHP better.


 [2007-08-03 12:53 UTC] thetaphi@php.net
The patch corrupts overwriting of ini entries in multithreaded webserver SJSWS (formerly iplanet/SunONE).

It seems that the INI entry is modified in a way that corrupts its further usage. I would suggest to change this patch that the modify_type in ini_entry->modifiable = ZEND_INI_SYSTEM should only be set in the replicated "modified" ini entry that is only available to the current request. Changing it in the global ini table corrupts it and stops further threads from modifying it (where no php_admin value is used and it should be overwriteable!)...

see discussion on internals@lists.php.net
 [2007-08-03 13:28 UTC] thetaphi@php.net
I suppose there is something special with error reporting that corrupts it. It seems that it does not like it to be changed to ZEND_INI_SYSTEM because the @operator tries to change the value (e.g. in zend_vm_execute.h), which fails silently:

static int ZEND_BEGIN_SILENCE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
	zend_op *opline = EX(opline);

	Z_LVAL(EX_T(opline->result.u.var).tmp_var) = EG(error_reporting);
	Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_LONG;  /* shouldn't be necessary */
	if (EX(old_error_reporting) == NULL) {
		EX(old_error_reporting) = &EX_T(opline->result.u.var).tmp_var;
	}

	if (EG(error_reporting)) {
		zend_alter_ini_entry("error_reporting", sizeof("error_reporting"), "0", 1, ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME);
	}
	ZEND_VM_NEXT_OPCODE();
}

=> When error_reporting was overwritten with ADMIN privileges it cannot be changed anymore by the @ operator :)

For my first idea where this bug comes from: You should move 
if (stage == ZEND_INI_STAGE_ACTIVATE && modify_type == ZEND_INI_SYSTEM) {
	ini_entry->modifiable = ZEND_INI_SYSTEM;
}
Behind the if-clause: "if (!modified) {..." to only modify the thread local ini-entry!
 [2007-08-31 07:55 UTC] jani@php.net
Patch re-applied, it's not the one causing above problems.
thetaphi: Open separate report about this.
 [2007-09-07 09:39 UTC] jani@php.net
To thetaphi@php.net: This is now fixed in CVS. (there was no thread issue at all, AFAICT..)
 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Fri Apr 18 23:01:58 2014 UTC